// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

#![allow(rustdoc::redundant_explicit_links)]
#![allow(rustdoc::broken_intra_doc_links)]
#![no_implicit_prelude]
extern crate api;
extern crate async_trait;
extern crate bytes;
extern crate gax;
extern crate gaxi;
extern crate gtype;
extern crate lazy_static;
extern crate longrunning;
extern crate lro;
extern crate reqwest;
extern crate rpc;
extern crate serde;
extern crate serde_json;
extern crate serde_with;
extern crate std;
extern crate tracing;
extern crate wkt;

mod debug;
mod deserialize;
mod serialize;

/// Configures what level the product should be uploaded with regards to
/// how users will be send events and how predictions will be made.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ProductLevelConfig {
    /// The type of [Product][google.cloud.retail.v2.Product]s allowed to be
    /// ingested into the catalog. Acceptable values are:
    ///
    /// * `primary` (default): You can ingest
    ///   [Product][google.cloud.retail.v2.Product]s of all types. When
    ///   ingesting a [Product][google.cloud.retail.v2.Product], its type will
    ///   default to
    ///   [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] if
    ///   unset.
    /// * `variant` (incompatible with Retail Search): You can only
    ///   ingest
    ///   [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
    ///   [Product][google.cloud.retail.v2.Product]s. This means
    ///   [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]
    ///   cannot be empty.
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// If this field is `variant` and
    /// [merchant_center_product_id_field][google.cloud.retail.v2.ProductLevelConfig.merchant_center_product_id_field]
    /// is `itemGroupId`, an INVALID_ARGUMENT error is returned.
    ///
    /// See [Product
    /// levels](https://cloud.google.com/retail/docs/catalog#product-levels)
    /// for more details.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.Product.primary_product_id]: crate::model::Product::primary_product_id
    /// [google.cloud.retail.v2.ProductLevelConfig.merchant_center_product_id_field]: crate::model::ProductLevelConfig::merchant_center_product_id_field
    pub ingestion_product_type: std::string::String,

    /// Which field of [Merchant Center
    /// Product](/bigquery-transfer/docs/merchant-center-products-schema) should be
    /// imported as [Product.id][google.cloud.retail.v2.Product.id]. Acceptable
    /// values are:
    ///
    /// * `offerId` (default): Import `offerId` as the product ID.
    /// * `itemGroupId`: Import `itemGroupId` as the product ID. Notice that Retail
    ///   API will choose one item from the ones with the same `itemGroupId`, and
    ///   use it to represent the item group.
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// If this field is `itemGroupId` and
    /// [ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type]
    /// is `variant`, an INVALID_ARGUMENT error is returned.
    ///
    /// See [Product
    /// levels](https://cloud.google.com/retail/docs/catalog#product-levels)
    /// for more details.
    ///
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    /// [google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type]: crate::model::ProductLevelConfig::ingestion_product_type
    pub merchant_center_product_id_field: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ProductLevelConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [ingestion_product_type][crate::model::ProductLevelConfig::ingestion_product_type].
    pub fn set_ingestion_product_type<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.ingestion_product_type = v.into();
        self
    }

    /// Sets the value of [merchant_center_product_id_field][crate::model::ProductLevelConfig::merchant_center_product_id_field].
    pub fn set_merchant_center_product_id_field<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.merchant_center_product_id_field = v.into();
        self
    }
}

impl wkt::message::Message for ProductLevelConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ProductLevelConfig"
    }
}

/// Catalog level attribute config for an attribute. For example, if customers
/// want to enable/disable facet for a specific attribute.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CatalogAttribute {
    /// Required. Attribute name.
    /// For example: `color`, `brands`, `attributes.custom_attribute`, such as
    /// `attributes.xyz`.
    /// To be indexable, the attribute name can contain only alpha-numeric
    /// characters and underscores. For example, an attribute named
    /// `attributes.abc_xyz` can be indexed, but an attribute named
    /// `attributes.abc-xyz` cannot be indexed.
    ///
    /// If the attribute key starts with `attributes.`, then the attribute is a
    /// custom attribute. Attributes such as `brands`, `patterns`, and `title` are
    /// built-in and called system attributes.
    pub key: std::string::String,

    /// Output only. Indicates whether this attribute has been used by any
    /// products. `True` if at least one [Product][google.cloud.retail.v2.Product]
    /// is using this attribute in
    /// [Product.attributes][google.cloud.retail.v2.Product.attributes]. Otherwise,
    /// this field is `False`.
    ///
    /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] can be
    /// pre-loaded by using
    /// [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute]
    /// or
    /// [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig]
    /// APIs. This field is `False` for pre-loaded
    /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute]s.
    ///
    /// Only pre-loaded [catalog
    /// attributes][google.cloud.retail.v2.CatalogAttribute] that are neither in
    /// use by products nor predefined can be deleted. [Catalog
    /// attributes][google.cloud.retail.v2.CatalogAttribute] that are
    /// either in use by products or are predefined attributes cannot be deleted;
    /// however, their configuration properties will reset to default values upon
    /// removal request.
    ///
    /// After catalog changes, it takes about 10 minutes for this field to update.
    ///
    /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
    /// [google.cloud.retail.v2.CatalogService.AddCatalogAttribute]: crate::client::CatalogService::add_catalog_attribute
    /// [google.cloud.retail.v2.CatalogService.UpdateAttributesConfig]: crate::client::CatalogService::update_attributes_config
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.attributes]: crate::model::Product::attributes
    pub in_use: bool,

    /// Output only. The type of this attribute. This is derived from the attribute
    /// in [Product.attributes][google.cloud.retail.v2.Product.attributes].
    ///
    /// [google.cloud.retail.v2.Product.attributes]: crate::model::Product::attributes
    pub r#type: crate::model::catalog_attribute::AttributeType,

    /// When
    /// [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level]
    /// is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if INDEXABLE_ENABLED attribute values
    /// are indexed so that it can be filtered, faceted, or boosted in
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search].
    ///
    /// Must be specified when
    /// [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level]
    /// is CATALOG_LEVEL_ATTRIBUTE_CONFIG, otherwise throws INVALID_FORMAT error.
    ///
    /// [google.cloud.retail.v2.AttributesConfig.attribute_config_level]: crate::model::AttributesConfig::attribute_config_level
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    pub indexable_option: crate::model::catalog_attribute::IndexableOption,

    /// If DYNAMIC_FACETABLE_ENABLED, attribute values are available for dynamic
    /// facet. Could only be DYNAMIC_FACETABLE_DISABLED if
    /// [CatalogAttribute.indexable_option][google.cloud.retail.v2.CatalogAttribute.indexable_option]
    /// is INDEXABLE_DISABLED. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Must be specified, otherwise throws INVALID_FORMAT error.
    ///
    /// [google.cloud.retail.v2.CatalogAttribute.indexable_option]: crate::model::CatalogAttribute::indexable_option
    pub dynamic_facetable_option: crate::model::catalog_attribute::DynamicFacetableOption,

    /// When
    /// [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level]
    /// is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if SEARCHABLE_ENABLED, attribute values
    /// are searchable by text queries in
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search].
    ///
    /// If SEARCHABLE_ENABLED but attribute type is numerical, attribute values
    /// will not be searchable by text queries in
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search], as
    /// there are no text values associated to numerical attributes.
    ///
    /// Must be specified, when
    /// [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level]
    /// is CATALOG_LEVEL_ATTRIBUTE_CONFIG, otherwise throws INVALID_FORMAT error.
    ///
    /// [google.cloud.retail.v2.AttributesConfig.attribute_config_level]: crate::model::AttributesConfig::attribute_config_level
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    pub searchable_option: crate::model::catalog_attribute::SearchableOption,

    /// If EXACT_SEARCHABLE_ENABLED, attribute values will be exact searchable.
    /// This property only applies to textual custom attributes and requires
    /// indexable set to enabled to enable exact-searchable. If unset, the server
    /// behavior defaults to
    /// [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED].
    ///
    /// [google.cloud.retail.v2.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]: crate::model::catalog_attribute::ExactSearchableOption::ExactSearchableDisabled
    pub exact_searchable_option: crate::model::catalog_attribute::ExactSearchableOption,

    /// If RETRIEVABLE_ENABLED, attribute values are retrievable in the search
    /// results. If unset, the server behavior defaults to
    /// [RETRIEVABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED].
    ///
    /// [google.cloud.retail.v2.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]: crate::model::catalog_attribute::RetrievableOption::RetrievableDisabled
    pub retrievable_option: crate::model::catalog_attribute::RetrievableOption,

    /// Contains facet options.
    pub facet_config: std::option::Option<crate::model::catalog_attribute::FacetConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CatalogAttribute {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [key][crate::model::CatalogAttribute::key].
    pub fn set_key<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.key = v.into();
        self
    }

    /// Sets the value of [in_use][crate::model::CatalogAttribute::in_use].
    pub fn set_in_use<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.in_use = v.into();
        self
    }

    /// Sets the value of [r#type][crate::model::CatalogAttribute::type].
    pub fn set_type<T: std::convert::Into<crate::model::catalog_attribute::AttributeType>>(
        mut self,
        v: T,
    ) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [indexable_option][crate::model::CatalogAttribute::indexable_option].
    pub fn set_indexable_option<
        T: std::convert::Into<crate::model::catalog_attribute::IndexableOption>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.indexable_option = v.into();
        self
    }

    /// Sets the value of [dynamic_facetable_option][crate::model::CatalogAttribute::dynamic_facetable_option].
    pub fn set_dynamic_facetable_option<
        T: std::convert::Into<crate::model::catalog_attribute::DynamicFacetableOption>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.dynamic_facetable_option = v.into();
        self
    }

    /// Sets the value of [searchable_option][crate::model::CatalogAttribute::searchable_option].
    pub fn set_searchable_option<
        T: std::convert::Into<crate::model::catalog_attribute::SearchableOption>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.searchable_option = v.into();
        self
    }

    /// Sets the value of [exact_searchable_option][crate::model::CatalogAttribute::exact_searchable_option].
    pub fn set_exact_searchable_option<
        T: std::convert::Into<crate::model::catalog_attribute::ExactSearchableOption>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.exact_searchable_option = v.into();
        self
    }

    /// Sets the value of [retrievable_option][crate::model::CatalogAttribute::retrievable_option].
    pub fn set_retrievable_option<
        T: std::convert::Into<crate::model::catalog_attribute::RetrievableOption>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.retrievable_option = v.into();
        self
    }

    /// Sets the value of [facet_config][crate::model::CatalogAttribute::facet_config].
    pub fn set_facet_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::catalog_attribute::FacetConfig>,
    {
        self.facet_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [facet_config][crate::model::CatalogAttribute::facet_config].
    pub fn set_or_clear_facet_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::catalog_attribute::FacetConfig>,
    {
        self.facet_config = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for CatalogAttribute {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CatalogAttribute"
    }
}

/// Defines additional types related to [CatalogAttribute].
pub mod catalog_attribute {
    #[allow(unused_imports)]
    use super::*;

    /// Possible options for the facet that corresponds to the current attribute
    /// config.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FacetConfig {
        /// If you don't set the facet
        /// [SearchRequest.FacetSpec.FacetKey.intervals][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals]
        /// in the request to a numerical attribute, then we use the computed
        /// intervals with rounded bounds obtained from all its product numerical
        /// attribute values. The computed intervals might not be ideal for some
        /// attributes. Therefore, we give you the option to overwrite them with the
        /// facet_intervals field. The maximum of facet intervals per
        /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] is 40. Each
        /// interval must have a lower bound or an upper bound. If both bounds are
        /// provided, then the lower bound must be smaller or equal than the upper
        /// bound.
        ///
        /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
        /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals]: crate::model::search_request::facet_spec::FacetKey::intervals
        pub facet_intervals: std::vec::Vec<crate::model::Interval>,

        /// Each instance represents a list of attribute values to ignore as facet
        /// values for a specific time range. The maximum number of instances per
        /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] is 25.
        ///
        /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
        pub ignored_facet_values:
            std::vec::Vec<crate::model::catalog_attribute::facet_config::IgnoredFacetValues>,

        /// Each instance replaces a list of facet values by a merged facet
        /// value. If a facet value is not in any list, then it will stay the same.
        /// To avoid conflicts, only paths of length 1 are accepted. In other words,
        /// if "dark_blue" merged into "BLUE", then the latter can't merge into
        /// "blues" because this would create a path of length 2. The maximum number
        /// of instances of MergedFacetValue per
        /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] is 100. This
        /// feature is available only for textual custom attributes.
        ///
        /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
        pub merged_facet_values:
            std::vec::Vec<crate::model::catalog_attribute::facet_config::MergedFacetValue>,

        /// Use this field only if you want to merge a facet key into another facet
        /// key.
        pub merged_facet:
            std::option::Option<crate::model::catalog_attribute::facet_config::MergedFacet>,

        /// Set this field only if you want to rerank based on facet values engaged
        /// by the user for the current key. This option is only possible for custom
        /// facetable textual keys.
        pub rerank_config:
            std::option::Option<crate::model::catalog_attribute::facet_config::RerankConfig>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FacetConfig {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [facet_intervals][crate::model::catalog_attribute::FacetConfig::facet_intervals].
        pub fn set_facet_intervals<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::Interval>,
        {
            use std::iter::Iterator;
            self.facet_intervals = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [ignored_facet_values][crate::model::catalog_attribute::FacetConfig::ignored_facet_values].
        pub fn set_ignored_facet_values<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<
                    crate::model::catalog_attribute::facet_config::IgnoredFacetValues,
                >,
        {
            use std::iter::Iterator;
            self.ignored_facet_values = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [merged_facet_values][crate::model::catalog_attribute::FacetConfig::merged_facet_values].
        pub fn set_merged_facet_values<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::catalog_attribute::facet_config::MergedFacetValue>,
        {
            use std::iter::Iterator;
            self.merged_facet_values = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [merged_facet][crate::model::catalog_attribute::FacetConfig::merged_facet].
        pub fn set_merged_facet<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::catalog_attribute::facet_config::MergedFacet>,
        {
            self.merged_facet = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [merged_facet][crate::model::catalog_attribute::FacetConfig::merged_facet].
        pub fn set_or_clear_merged_facet<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::catalog_attribute::facet_config::MergedFacet>,
        {
            self.merged_facet = v.map(|x| x.into());
            self
        }

        /// Sets the value of [rerank_config][crate::model::catalog_attribute::FacetConfig::rerank_config].
        pub fn set_rerank_config<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::catalog_attribute::facet_config::RerankConfig>,
        {
            self.rerank_config = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [rerank_config][crate::model::catalog_attribute::FacetConfig::rerank_config].
        pub fn set_or_clear_rerank_config<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::catalog_attribute::facet_config::RerankConfig>,
        {
            self.rerank_config = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for FacetConfig {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.CatalogAttribute.FacetConfig"
        }
    }

    /// Defines additional types related to [FacetConfig].
    pub mod facet_config {
        #[allow(unused_imports)]
        use super::*;

        /// [Facet values][google.cloud.retail.v2.SearchResponse.Facet.values] to
        /// ignore on [facets][google.cloud.retail.v2.SearchResponse.Facet] during
        /// the specified time range for the given
        /// [SearchResponse.Facet.key][google.cloud.retail.v2.SearchResponse.Facet.key]
        /// attribute.
        ///
        /// [google.cloud.retail.v2.SearchResponse.Facet]: crate::model::search_response::Facet
        /// [google.cloud.retail.v2.SearchResponse.Facet.key]: crate::model::search_response::Facet::key
        /// [google.cloud.retail.v2.SearchResponse.Facet.values]: crate::model::search_response::Facet::values
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct IgnoredFacetValues {
            /// List of facet values to ignore for the following time range. The facet
            /// values are the same as the attribute values. There is a limit of 10
            /// values per instance of IgnoredFacetValues. Each value can have at most
            /// 128 characters.
            pub values: std::vec::Vec<std::string::String>,

            /// Time range for the current list of facet values to ignore.
            /// If multiple time ranges are specified for an facet value for the
            /// current attribute, consider all of them. If both are empty, ignore
            /// always. If start time and end time are set, then start time
            /// must be before end time.
            /// If start time is not empty and end time is empty, then will ignore
            /// these facet values after the start time.
            pub start_time: std::option::Option<wkt::Timestamp>,

            /// If start time is empty and end time is not empty, then ignore these
            /// facet values before end time.
            pub end_time: std::option::Option<wkt::Timestamp>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl IgnoredFacetValues {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [values][crate::model::catalog_attribute::facet_config::IgnoredFacetValues::values].
            pub fn set_values<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<std::string::String>,
            {
                use std::iter::Iterator;
                self.values = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [start_time][crate::model::catalog_attribute::facet_config::IgnoredFacetValues::start_time].
            pub fn set_start_time<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.start_time = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [start_time][crate::model::catalog_attribute::facet_config::IgnoredFacetValues::start_time].
            pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.start_time = v.map(|x| x.into());
                self
            }

            /// Sets the value of [end_time][crate::model::catalog_attribute::facet_config::IgnoredFacetValues::end_time].
            pub fn set_end_time<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.end_time = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [end_time][crate::model::catalog_attribute::facet_config::IgnoredFacetValues::end_time].
            pub fn set_or_clear_end_time<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.end_time = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for IgnoredFacetValues {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.CatalogAttribute.FacetConfig.IgnoredFacetValues"
            }
        }

        /// Replaces a set of textual facet values by the same (possibly different)
        /// merged facet value. Each facet value should appear at most once as a
        /// value per [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute].
        /// This feature is available only for textual custom attributes.
        ///
        /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct MergedFacetValue {
            /// All the facet values that are replaces by the same
            /// [merged_value][google.cloud.retail.v2.CatalogAttribute.FacetConfig.MergedFacetValue.merged_value]
            /// that follows. The maximum number of values per MergedFacetValue is 25.
            /// Each value can have up to 128 characters.
            ///
            /// [google.cloud.retail.v2.CatalogAttribute.FacetConfig.MergedFacetValue.merged_value]: crate::model::catalog_attribute::facet_config::MergedFacetValue::merged_value
            pub values: std::vec::Vec<std::string::String>,

            /// All the previous values are replaced by this merged facet value.
            /// This merged_value must be non-empty and can have up to 128 characters.
            pub merged_value: std::string::String,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl MergedFacetValue {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [values][crate::model::catalog_attribute::facet_config::MergedFacetValue::values].
            pub fn set_values<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<std::string::String>,
            {
                use std::iter::Iterator;
                self.values = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [merged_value][crate::model::catalog_attribute::facet_config::MergedFacetValue::merged_value].
            pub fn set_merged_value<T: std::convert::Into<std::string::String>>(
                mut self,
                v: T,
            ) -> Self {
                self.merged_value = v.into();
                self
            }
        }

        impl wkt::message::Message for MergedFacetValue {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.CatalogAttribute.FacetConfig.MergedFacetValue"
            }
        }

        /// The current facet key (i.e. attribute config) maps into the
        /// [merged_facet_key][google.cloud.retail.v2.CatalogAttribute.FacetConfig.MergedFacet.merged_facet_key].
        /// A facet key can have at most one child. The current facet key and the
        /// merged facet key need both to be textual custom attributes or both
        /// numerical custom attributes (same type).
        ///
        /// [google.cloud.retail.v2.CatalogAttribute.FacetConfig.MergedFacet.merged_facet_key]: crate::model::catalog_attribute::facet_config::MergedFacet::merged_facet_key
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct MergedFacet {
            /// The merged facet key should be a valid facet key that is different than
            /// the facet key of the current catalog attribute. We refer this is
            /// merged facet key as the child of the current catalog attribute. This
            /// merged facet key can't be a parent of another facet key (i.e. no
            /// directed path of length 2). This merged facet key needs to be either a
            /// textual custom attribute or a numerical custom attribute.
            pub merged_facet_key: std::string::String,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl MergedFacet {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [merged_facet_key][crate::model::catalog_attribute::facet_config::MergedFacet::merged_facet_key].
            pub fn set_merged_facet_key<T: std::convert::Into<std::string::String>>(
                mut self,
                v: T,
            ) -> Self {
                self.merged_facet_key = v.into();
                self
            }
        }

        impl wkt::message::Message for MergedFacet {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.CatalogAttribute.FacetConfig.MergedFacet"
            }
        }

        /// Options to rerank based on facet values engaged by the user for the
        /// current key. That key needs to be a custom textual key and facetable.
        /// To use this control, you also need to pass all the facet keys engaged by
        /// the user in the request using the field [SearchRequest.FacetSpec]. In
        /// particular, if you don't pass the facet keys engaged that you want to
        /// rerank on, this control won't be effective. Moreover, to obtain better
        /// results, the facet values that you want to rerank on should be close to
        /// English (ideally made of words, underscores, and spaces).
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct RerankConfig {
            /// If set to true, then we also rerank the dynamic facets based on the
            /// facet values engaged by the user for the current attribute key during
            /// serving.
            pub rerank_facet: bool,

            /// If empty, rerank on all facet values for the current key. Otherwise,
            /// will rerank on the facet values from this list only.
            pub facet_values: std::vec::Vec<std::string::String>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl RerankConfig {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [rerank_facet][crate::model::catalog_attribute::facet_config::RerankConfig::rerank_facet].
            pub fn set_rerank_facet<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
                self.rerank_facet = v.into();
                self
            }

            /// Sets the value of [facet_values][crate::model::catalog_attribute::facet_config::RerankConfig::facet_values].
            pub fn set_facet_values<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<std::string::String>,
            {
                use std::iter::Iterator;
                self.facet_values = v.into_iter().map(|i| i.into()).collect();
                self
            }
        }

        impl wkt::message::Message for RerankConfig {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.CatalogAttribute.FacetConfig.RerankConfig"
            }
        }
    }

    /// The type of an attribute.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum AttributeType {
        /// The type of the attribute is unknown.
        ///
        /// Used when type cannot be derived from attribute that is not
        /// [in_use][google.cloud.retail.v2.CatalogAttribute.in_use].
        ///
        /// [google.cloud.retail.v2.CatalogAttribute.in_use]: crate::model::CatalogAttribute::in_use
        Unknown,
        /// Textual attribute.
        Textual,
        /// Numerical attribute.
        Numerical,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [AttributeType::value] or
        /// [AttributeType::name].
        UnknownValue(attribute_type::UnknownValue),
    }

    #[doc(hidden)]
    pub mod attribute_type {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl AttributeType {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unknown => std::option::Option::Some(0),
                Self::Textual => std::option::Option::Some(1),
                Self::Numerical => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unknown => std::option::Option::Some("UNKNOWN"),
                Self::Textual => std::option::Option::Some("TEXTUAL"),
                Self::Numerical => std::option::Option::Some("NUMERICAL"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for AttributeType {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for AttributeType {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for AttributeType {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unknown,
                1 => Self::Textual,
                2 => Self::Numerical,
                _ => Self::UnknownValue(attribute_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for AttributeType {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "UNKNOWN" => Self::Unknown,
                "TEXTUAL" => Self::Textual,
                "NUMERICAL" => Self::Numerical,
                _ => Self::UnknownValue(attribute_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for AttributeType {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unknown => serializer.serialize_i32(0),
                Self::Textual => serializer.serialize_i32(1),
                Self::Numerical => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for AttributeType {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<AttributeType>::new(
                ".google.cloud.retail.v2.CatalogAttribute.AttributeType",
            ))
        }
    }

    /// The status of the indexable option of a catalog attribute.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum IndexableOption {
        /// Value used when unset.
        Unspecified,
        /// Indexable option enabled for an attribute.
        IndexableEnabled,
        /// Indexable option disabled for an attribute.
        IndexableDisabled,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [IndexableOption::value] or
        /// [IndexableOption::name].
        UnknownValue(indexable_option::UnknownValue),
    }

    #[doc(hidden)]
    pub mod indexable_option {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl IndexableOption {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::IndexableEnabled => std::option::Option::Some(1),
                Self::IndexableDisabled => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("INDEXABLE_OPTION_UNSPECIFIED"),
                Self::IndexableEnabled => std::option::Option::Some("INDEXABLE_ENABLED"),
                Self::IndexableDisabled => std::option::Option::Some("INDEXABLE_DISABLED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for IndexableOption {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for IndexableOption {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for IndexableOption {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::IndexableEnabled,
                2 => Self::IndexableDisabled,
                _ => Self::UnknownValue(indexable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for IndexableOption {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "INDEXABLE_OPTION_UNSPECIFIED" => Self::Unspecified,
                "INDEXABLE_ENABLED" => Self::IndexableEnabled,
                "INDEXABLE_DISABLED" => Self::IndexableDisabled,
                _ => Self::UnknownValue(indexable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for IndexableOption {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::IndexableEnabled => serializer.serialize_i32(1),
                Self::IndexableDisabled => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for IndexableOption {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<IndexableOption>::new(
                ".google.cloud.retail.v2.CatalogAttribute.IndexableOption",
            ))
        }
    }

    /// The status of the dynamic facetable option of a catalog attribute.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum DynamicFacetableOption {
        /// Value used when unset.
        Unspecified,
        /// Dynamic facetable option enabled for an attribute.
        DynamicFacetableEnabled,
        /// Dynamic facetable option disabled for an attribute.
        DynamicFacetableDisabled,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [DynamicFacetableOption::value] or
        /// [DynamicFacetableOption::name].
        UnknownValue(dynamic_facetable_option::UnknownValue),
    }

    #[doc(hidden)]
    pub mod dynamic_facetable_option {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl DynamicFacetableOption {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::DynamicFacetableEnabled => std::option::Option::Some(1),
                Self::DynamicFacetableDisabled => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => {
                    std::option::Option::Some("DYNAMIC_FACETABLE_OPTION_UNSPECIFIED")
                }
                Self::DynamicFacetableEnabled => {
                    std::option::Option::Some("DYNAMIC_FACETABLE_ENABLED")
                }
                Self::DynamicFacetableDisabled => {
                    std::option::Option::Some("DYNAMIC_FACETABLE_DISABLED")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for DynamicFacetableOption {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for DynamicFacetableOption {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for DynamicFacetableOption {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::DynamicFacetableEnabled,
                2 => Self::DynamicFacetableDisabled,
                _ => Self::UnknownValue(dynamic_facetable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for DynamicFacetableOption {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "DYNAMIC_FACETABLE_OPTION_UNSPECIFIED" => Self::Unspecified,
                "DYNAMIC_FACETABLE_ENABLED" => Self::DynamicFacetableEnabled,
                "DYNAMIC_FACETABLE_DISABLED" => Self::DynamicFacetableDisabled,
                _ => Self::UnknownValue(dynamic_facetable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for DynamicFacetableOption {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::DynamicFacetableEnabled => serializer.serialize_i32(1),
                Self::DynamicFacetableDisabled => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for DynamicFacetableOption {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<DynamicFacetableOption>::new(
                ".google.cloud.retail.v2.CatalogAttribute.DynamicFacetableOption",
            ))
        }
    }

    /// The status of the searchable option of a catalog attribute.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum SearchableOption {
        /// Value used when unset.
        Unspecified,
        /// Searchable option enabled for an attribute.
        SearchableEnabled,
        /// Searchable option disabled for an attribute.
        SearchableDisabled,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [SearchableOption::value] or
        /// [SearchableOption::name].
        UnknownValue(searchable_option::UnknownValue),
    }

    #[doc(hidden)]
    pub mod searchable_option {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl SearchableOption {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::SearchableEnabled => std::option::Option::Some(1),
                Self::SearchableDisabled => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("SEARCHABLE_OPTION_UNSPECIFIED"),
                Self::SearchableEnabled => std::option::Option::Some("SEARCHABLE_ENABLED"),
                Self::SearchableDisabled => std::option::Option::Some("SEARCHABLE_DISABLED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for SearchableOption {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for SearchableOption {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for SearchableOption {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::SearchableEnabled,
                2 => Self::SearchableDisabled,
                _ => Self::UnknownValue(searchable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for SearchableOption {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "SEARCHABLE_OPTION_UNSPECIFIED" => Self::Unspecified,
                "SEARCHABLE_ENABLED" => Self::SearchableEnabled,
                "SEARCHABLE_DISABLED" => Self::SearchableDisabled,
                _ => Self::UnknownValue(searchable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for SearchableOption {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::SearchableEnabled => serializer.serialize_i32(1),
                Self::SearchableDisabled => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for SearchableOption {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<SearchableOption>::new(
                ".google.cloud.retail.v2.CatalogAttribute.SearchableOption",
            ))
        }
    }

    /// The status of the exact-searchable option of a catalog attribute.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ExactSearchableOption {
        /// Value used when unset.
        Unspecified,
        /// Exact searchable option enabled for an attribute.
        ExactSearchableEnabled,
        /// Exact searchable option disabled for an attribute.
        ExactSearchableDisabled,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [ExactSearchableOption::value] or
        /// [ExactSearchableOption::name].
        UnknownValue(exact_searchable_option::UnknownValue),
    }

    #[doc(hidden)]
    pub mod exact_searchable_option {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl ExactSearchableOption {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::ExactSearchableEnabled => std::option::Option::Some(1),
                Self::ExactSearchableDisabled => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => {
                    std::option::Option::Some("EXACT_SEARCHABLE_OPTION_UNSPECIFIED")
                }
                Self::ExactSearchableEnabled => {
                    std::option::Option::Some("EXACT_SEARCHABLE_ENABLED")
                }
                Self::ExactSearchableDisabled => {
                    std::option::Option::Some("EXACT_SEARCHABLE_DISABLED")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for ExactSearchableOption {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for ExactSearchableOption {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for ExactSearchableOption {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::ExactSearchableEnabled,
                2 => Self::ExactSearchableDisabled,
                _ => Self::UnknownValue(exact_searchable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for ExactSearchableOption {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "EXACT_SEARCHABLE_OPTION_UNSPECIFIED" => Self::Unspecified,
                "EXACT_SEARCHABLE_ENABLED" => Self::ExactSearchableEnabled,
                "EXACT_SEARCHABLE_DISABLED" => Self::ExactSearchableDisabled,
                _ => Self::UnknownValue(exact_searchable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for ExactSearchableOption {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::ExactSearchableEnabled => serializer.serialize_i32(1),
                Self::ExactSearchableDisabled => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for ExactSearchableOption {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<ExactSearchableOption>::new(
                ".google.cloud.retail.v2.CatalogAttribute.ExactSearchableOption",
            ))
        }
    }

    /// The status of the retrievable option of a catalog attribute.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum RetrievableOption {
        /// Value used when unset.
        Unspecified,
        /// Retrievable option enabled for an attribute.
        RetrievableEnabled,
        /// Retrievable option disabled for an attribute.
        RetrievableDisabled,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [RetrievableOption::value] or
        /// [RetrievableOption::name].
        UnknownValue(retrievable_option::UnknownValue),
    }

    #[doc(hidden)]
    pub mod retrievable_option {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl RetrievableOption {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::RetrievableEnabled => std::option::Option::Some(1),
                Self::RetrievableDisabled => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("RETRIEVABLE_OPTION_UNSPECIFIED"),
                Self::RetrievableEnabled => std::option::Option::Some("RETRIEVABLE_ENABLED"),
                Self::RetrievableDisabled => std::option::Option::Some("RETRIEVABLE_DISABLED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for RetrievableOption {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for RetrievableOption {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for RetrievableOption {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::RetrievableEnabled,
                2 => Self::RetrievableDisabled,
                _ => Self::UnknownValue(retrievable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for RetrievableOption {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "RETRIEVABLE_OPTION_UNSPECIFIED" => Self::Unspecified,
                "RETRIEVABLE_ENABLED" => Self::RetrievableEnabled,
                "RETRIEVABLE_DISABLED" => Self::RetrievableDisabled,
                _ => Self::UnknownValue(retrievable_option::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for RetrievableOption {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::RetrievableEnabled => serializer.serialize_i32(1),
                Self::RetrievableDisabled => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for RetrievableOption {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<RetrievableOption>::new(
                ".google.cloud.retail.v2.CatalogAttribute.RetrievableOption",
            ))
        }
    }
}

/// Catalog level attribute config.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AttributesConfig {
    /// Required. Immutable. The fully qualified resource name of the attribute
    /// config. Format: `projects/*/locations/*/catalogs/*/attributesConfig`
    pub name: std::string::String,

    /// Enable attribute(s) config at catalog level.
    /// For example, indexable, dynamic_facetable, or searchable for each
    /// attribute.
    ///
    /// The key is catalog attribute's name.
    /// For example: `color`, `brands`, `attributes.custom_attribute`, such as
    /// `attributes.xyz`.
    ///
    /// The maximum number of catalog attributes allowed in a request is 1000.
    pub catalog_attributes:
        std::collections::HashMap<std::string::String, crate::model::CatalogAttribute>,

    /// Output only. The
    /// [AttributeConfigLevel][google.cloud.retail.v2.AttributeConfigLevel] used
    /// for this catalog.
    ///
    /// [google.cloud.retail.v2.AttributeConfigLevel]: crate::model::AttributeConfigLevel
    pub attribute_config_level: crate::model::AttributeConfigLevel,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AttributesConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::AttributesConfig::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [catalog_attributes][crate::model::AttributesConfig::catalog_attributes].
    pub fn set_catalog_attributes<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::CatalogAttribute>,
    {
        use std::iter::Iterator;
        self.catalog_attributes = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [attribute_config_level][crate::model::AttributesConfig::attribute_config_level].
    pub fn set_attribute_config_level<T: std::convert::Into<crate::model::AttributeConfigLevel>>(
        mut self,
        v: T,
    ) -> Self {
        self.attribute_config_level = v.into();
        self
    }
}

impl wkt::message::Message for AttributesConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AttributesConfig"
    }
}

/// Catalog level autocomplete config for customers to customize autocomplete
/// feature's settings.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CompletionConfig {
    /// Required. Immutable. Fully qualified name
    /// `projects/*/locations/*/catalogs/*/completionConfig`
    pub name: std::string::String,

    /// Specifies the matching order for autocomplete suggestions, e.g., a query
    /// consisting of 'sh' with 'out-of-order' specified would suggest "women's
    /// shoes", whereas a query of 'red s' with 'exact-prefix' specified would
    /// suggest "red shoes". Currently supported values:
    ///
    /// * 'out-of-order'
    /// * 'exact-prefix'
    ///
    /// Default value: 'exact-prefix'.
    pub matching_order: std::string::String,

    /// The maximum number of autocomplete suggestions returned per term. Default
    /// value is 20. If left unset or set to 0, then will fallback to default
    /// value.
    ///
    /// Value range is 1 to 20.
    pub max_suggestions: i32,

    /// The minimum number of characters needed to be typed in order to get
    /// suggestions. Default value is 2. If left unset or set to 0, then will
    /// fallback to default value.
    ///
    /// Value range is 1 to 20.
    pub min_prefix_length: i32,

    /// If set to true, the auto learning function is enabled. Auto learning uses
    /// user data to generate suggestions using ML techniques. Default value is
    /// false. Only after enabling auto learning can users use `cloud-retail`
    /// data in
    /// [CompleteQueryRequest][google.cloud.retail.v2.CompleteQueryRequest].
    ///
    /// [google.cloud.retail.v2.CompleteQueryRequest]: crate::model::CompleteQueryRequest
    pub auto_learning: bool,

    /// Output only. The source data for the latest import of the autocomplete
    /// suggestion phrases.
    pub suggestions_input_config: std::option::Option<crate::model::CompletionDataInputConfig>,

    /// Output only. Name of the LRO corresponding to the latest suggestion terms
    /// list import.
    ///
    /// Can use [GetOperation][google.longrunning.Operations.GetOperation] API
    /// method to retrieve the latest state of the Long Running Operation.
    pub last_suggestions_import_operation: std::string::String,

    /// Output only. The source data for the latest import of the autocomplete
    /// denylist phrases.
    pub denylist_input_config: std::option::Option<crate::model::CompletionDataInputConfig>,

    /// Output only. Name of the LRO corresponding to the latest denylist import.
    ///
    /// Can use [GetOperation][google.longrunning.Operations.GetOperation] API to
    /// retrieve the latest state of the Long Running Operation.
    pub last_denylist_import_operation: std::string::String,

    /// Output only. The source data for the latest import of the autocomplete
    /// allowlist phrases.
    pub allowlist_input_config: std::option::Option<crate::model::CompletionDataInputConfig>,

    /// Output only. Name of the LRO corresponding to the latest allowlist import.
    ///
    /// Can use [GetOperation][google.longrunning.Operations.GetOperation] API to
    /// retrieve the latest state of the Long Running Operation.
    pub last_allowlist_import_operation: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CompletionConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::CompletionConfig::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [matching_order][crate::model::CompletionConfig::matching_order].
    pub fn set_matching_order<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.matching_order = v.into();
        self
    }

    /// Sets the value of [max_suggestions][crate::model::CompletionConfig::max_suggestions].
    pub fn set_max_suggestions<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.max_suggestions = v.into();
        self
    }

    /// Sets the value of [min_prefix_length][crate::model::CompletionConfig::min_prefix_length].
    pub fn set_min_prefix_length<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.min_prefix_length = v.into();
        self
    }

    /// Sets the value of [auto_learning][crate::model::CompletionConfig::auto_learning].
    pub fn set_auto_learning<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.auto_learning = v.into();
        self
    }

    /// Sets the value of [suggestions_input_config][crate::model::CompletionConfig::suggestions_input_config].
    pub fn set_suggestions_input_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.suggestions_input_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [suggestions_input_config][crate::model::CompletionConfig::suggestions_input_config].
    pub fn set_or_clear_suggestions_input_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.suggestions_input_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [last_suggestions_import_operation][crate::model::CompletionConfig::last_suggestions_import_operation].
    pub fn set_last_suggestions_import_operation<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.last_suggestions_import_operation = v.into();
        self
    }

    /// Sets the value of [denylist_input_config][crate::model::CompletionConfig::denylist_input_config].
    pub fn set_denylist_input_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.denylist_input_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [denylist_input_config][crate::model::CompletionConfig::denylist_input_config].
    pub fn set_or_clear_denylist_input_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.denylist_input_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [last_denylist_import_operation][crate::model::CompletionConfig::last_denylist_import_operation].
    pub fn set_last_denylist_import_operation<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.last_denylist_import_operation = v.into();
        self
    }

    /// Sets the value of [allowlist_input_config][crate::model::CompletionConfig::allowlist_input_config].
    pub fn set_allowlist_input_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.allowlist_input_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [allowlist_input_config][crate::model::CompletionConfig::allowlist_input_config].
    pub fn set_or_clear_allowlist_input_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.allowlist_input_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [last_allowlist_import_operation][crate::model::CompletionConfig::last_allowlist_import_operation].
    pub fn set_last_allowlist_import_operation<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.last_allowlist_import_operation = v.into();
        self
    }
}

impl wkt::message::Message for CompletionConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CompletionConfig"
    }
}

/// The catalog configuration.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Catalog {
    /// Required. Immutable. The fully qualified resource name of the catalog.
    pub name: std::string::String,

    /// Required. Immutable. The catalog display name.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    pub display_name: std::string::String,

    /// Required. The product level configuration.
    pub product_level_config: std::option::Option<crate::model::ProductLevelConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Catalog {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::Catalog::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [display_name][crate::model::Catalog::display_name].
    pub fn set_display_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.display_name = v.into();
        self
    }

    /// Sets the value of [product_level_config][crate::model::Catalog::product_level_config].
    pub fn set_product_level_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ProductLevelConfig>,
    {
        self.product_level_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [product_level_config][crate::model::Catalog::product_level_config].
    pub fn set_or_clear_product_level_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ProductLevelConfig>,
    {
        self.product_level_config = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for Catalog {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Catalog"
    }
}

/// Request for
/// [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.ListCatalogs]: crate::client::CatalogService::list_catalogs
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListCatalogsRequest {
    /// Required. The account resource name with an associated location.
    ///
    /// If the caller does not have permission to list
    /// [Catalog][google.cloud.retail.v2.Catalog]s under this location, regardless
    /// of whether or not this location exists, a PERMISSION_DENIED error is
    /// returned.
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    pub parent: std::string::String,

    /// Maximum number of [Catalog][google.cloud.retail.v2.Catalog]s to return. If
    /// unspecified, defaults to 50. The maximum allowed value is 1000. Values
    /// above 1000 will be coerced to 1000.
    ///
    /// If this field is negative, an INVALID_ARGUMENT is returned.
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    pub page_size: i32,

    /// A page token
    /// [ListCatalogsResponse.next_page_token][google.cloud.retail.v2.ListCatalogsResponse.next_page_token],
    /// received from a previous
    /// [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs]
    /// call. Provide this to retrieve the subsequent page.
    ///
    /// When paginating, all other parameters provided to
    /// [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs]
    /// must match the call that provided the page token. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.CatalogService.ListCatalogs]: crate::client::CatalogService::list_catalogs
    /// [google.cloud.retail.v2.ListCatalogsResponse.next_page_token]: crate::model::ListCatalogsResponse::next_page_token
    pub page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListCatalogsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListCatalogsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListCatalogsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListCatalogsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListCatalogsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListCatalogsRequest"
    }
}

/// Response for
/// [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.ListCatalogs]: crate::client::CatalogService::list_catalogs
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListCatalogsResponse {
    /// All the customer's [Catalog][google.cloud.retail.v2.Catalog]s.
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    pub catalogs: std::vec::Vec<crate::model::Catalog>,

    /// A token that can be sent as
    /// [ListCatalogsRequest.page_token][google.cloud.retail.v2.ListCatalogsRequest.page_token]
    /// to retrieve the next page. If this field is omitted, there are no
    /// subsequent pages.
    ///
    /// [google.cloud.retail.v2.ListCatalogsRequest.page_token]: crate::model::ListCatalogsRequest::page_token
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListCatalogsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalogs][crate::model::ListCatalogsResponse::catalogs].
    pub fn set_catalogs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Catalog>,
    {
        use std::iter::Iterator;
        self.catalogs = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListCatalogsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListCatalogsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListCatalogsResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for ListCatalogsResponse {
    type PageItem = crate::model::Catalog;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.catalogs
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// Request for
/// [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.UpdateCatalog]: crate::client::CatalogService::update_catalog
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateCatalogRequest {
    /// Required. The [Catalog][google.cloud.retail.v2.Catalog] to update.
    ///
    /// If the caller does not have permission to update the
    /// [Catalog][google.cloud.retail.v2.Catalog], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// If the [Catalog][google.cloud.retail.v2.Catalog] to update does not exist,
    /// a NOT_FOUND error is returned.
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    pub catalog: std::option::Option<crate::model::Catalog>,

    /// Indicates which fields in the provided
    /// [Catalog][google.cloud.retail.v2.Catalog] to update.
    ///
    /// If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
    /// is returned.
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateCatalogRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::UpdateCatalogRequest::catalog].
    pub fn set_catalog<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Catalog>,
    {
        self.catalog = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [catalog][crate::model::UpdateCatalogRequest::catalog].
    pub fn set_or_clear_catalog<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Catalog>,
    {
        self.catalog = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateCatalogRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateCatalogRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateCatalogRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateCatalogRequest"
    }
}

/// Request message to set a specified branch as new default_branch.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SetDefaultBranchRequest {
    /// Full resource name of the catalog, such as
    /// `projects/*/locations/global/catalogs/default_catalog`.
    pub catalog: std::string::String,

    /// The final component of the resource name of a branch.
    ///
    /// This field must be one of "0", "1" or "2". Otherwise, an INVALID_ARGUMENT
    /// error is returned.
    ///
    /// If there are no sufficient active products in the targeted branch and
    /// [force][google.cloud.retail.v2.SetDefaultBranchRequest.force] is not set, a
    /// FAILED_PRECONDITION error is returned.
    ///
    /// [google.cloud.retail.v2.SetDefaultBranchRequest.force]: crate::model::SetDefaultBranchRequest::force
    pub branch_id: std::string::String,

    /// Some note on this request, this can be retrieved by
    /// [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]
    /// before next valid default branch set occurs.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 1,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.CatalogService.GetDefaultBranch]: crate::client::CatalogService::get_default_branch
    pub note: std::string::String,

    /// If set to true, it permits switching to a branch with
    /// [branch_id][google.cloud.retail.v2.SetDefaultBranchRequest.branch_id] even
    /// if it has no sufficient active products.
    ///
    /// [google.cloud.retail.v2.SetDefaultBranchRequest.branch_id]: crate::model::SetDefaultBranchRequest::branch_id
    pub force: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SetDefaultBranchRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::SetDefaultBranchRequest::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }

    /// Sets the value of [branch_id][crate::model::SetDefaultBranchRequest::branch_id].
    pub fn set_branch_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.branch_id = v.into();
        self
    }

    /// Sets the value of [note][crate::model::SetDefaultBranchRequest::note].
    pub fn set_note<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.note = v.into();
        self
    }

    /// Sets the value of [force][crate::model::SetDefaultBranchRequest::force].
    pub fn set_force<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.force = v.into();
        self
    }
}

impl wkt::message::Message for SetDefaultBranchRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SetDefaultBranchRequest"
    }
}

/// Request message to show which branch is currently the default branch.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetDefaultBranchRequest {
    /// The parent catalog resource name, such as
    /// `projects/*/locations/global/catalogs/default_catalog`.
    pub catalog: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetDefaultBranchRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::GetDefaultBranchRequest::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }
}

impl wkt::message::Message for GetDefaultBranchRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetDefaultBranchRequest"
    }
}

/// Response message of
/// [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch].
///
/// [google.cloud.retail.v2.CatalogService.GetDefaultBranch]: crate::client::CatalogService::get_default_branch
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetDefaultBranchResponse {
    /// Full resource name of the branch id currently set as default branch.
    pub branch: std::string::String,

    /// The time when this branch is set to default.
    pub set_time: std::option::Option<wkt::Timestamp>,

    /// This corresponds to
    /// [SetDefaultBranchRequest.note][google.cloud.retail.v2.SetDefaultBranchRequest.note]
    /// field, when this branch was set as default.
    ///
    /// [google.cloud.retail.v2.SetDefaultBranchRequest.note]: crate::model::SetDefaultBranchRequest::note
    pub note: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetDefaultBranchResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [branch][crate::model::GetDefaultBranchResponse::branch].
    pub fn set_branch<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.branch = v.into();
        self
    }

    /// Sets the value of [set_time][crate::model::GetDefaultBranchResponse::set_time].
    pub fn set_set_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.set_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [set_time][crate::model::GetDefaultBranchResponse::set_time].
    pub fn set_or_clear_set_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.set_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [note][crate::model::GetDefaultBranchResponse::note].
    pub fn set_note<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.note = v.into();
        self
    }
}

impl wkt::message::Message for GetDefaultBranchResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetDefaultBranchResponse"
    }
}

/// Request for
/// [CatalogService.GetCompletionConfig][google.cloud.retail.v2.CatalogService.GetCompletionConfig]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.GetCompletionConfig]: crate::client::CatalogService::get_completion_config
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetCompletionConfigRequest {
    /// Required. Full CompletionConfig resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetCompletionConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetCompletionConfigRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for GetCompletionConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetCompletionConfigRequest"
    }
}

/// Request for
/// [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2.CatalogService.UpdateCompletionConfig]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.UpdateCompletionConfig]: crate::client::CatalogService::update_completion_config
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateCompletionConfigRequest {
    /// Required. The [CompletionConfig][google.cloud.retail.v2.CompletionConfig]
    /// to update.
    ///
    /// If the caller does not have permission to update the
    /// [CompletionConfig][google.cloud.retail.v2.CompletionConfig], then a
    /// PERMISSION_DENIED error is returned.
    ///
    /// If the [CompletionConfig][google.cloud.retail.v2.CompletionConfig] to
    /// update does not exist, a NOT_FOUND error is returned.
    ///
    /// [google.cloud.retail.v2.CompletionConfig]: crate::model::CompletionConfig
    pub completion_config: std::option::Option<crate::model::CompletionConfig>,

    /// Indicates which fields in the provided
    /// [CompletionConfig][google.cloud.retail.v2.CompletionConfig] to update. The
    /// following are the only supported fields:
    ///
    /// * [CompletionConfig.matching_order][google.cloud.retail.v2.CompletionConfig.matching_order]
    /// * [CompletionConfig.max_suggestions][google.cloud.retail.v2.CompletionConfig.max_suggestions]
    /// * [CompletionConfig.min_prefix_length][google.cloud.retail.v2.CompletionConfig.min_prefix_length]
    /// * [CompletionConfig.auto_learning][google.cloud.retail.v2.CompletionConfig.auto_learning]
    ///
    /// If not set, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.CompletionConfig]: crate::model::CompletionConfig
    /// [google.cloud.retail.v2.CompletionConfig.auto_learning]: crate::model::CompletionConfig::auto_learning
    /// [google.cloud.retail.v2.CompletionConfig.matching_order]: crate::model::CompletionConfig::matching_order
    /// [google.cloud.retail.v2.CompletionConfig.max_suggestions]: crate::model::CompletionConfig::max_suggestions
    /// [google.cloud.retail.v2.CompletionConfig.min_prefix_length]: crate::model::CompletionConfig::min_prefix_length
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateCompletionConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [completion_config][crate::model::UpdateCompletionConfigRequest::completion_config].
    pub fn set_completion_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CompletionConfig>,
    {
        self.completion_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [completion_config][crate::model::UpdateCompletionConfigRequest::completion_config].
    pub fn set_or_clear_completion_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CompletionConfig>,
    {
        self.completion_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateCompletionConfigRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateCompletionConfigRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateCompletionConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateCompletionConfigRequest"
    }
}

/// Request for
/// [CatalogService.GetAttributesConfig][google.cloud.retail.v2.CatalogService.GetAttributesConfig]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.GetAttributesConfig]: crate::client::CatalogService::get_attributes_config
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetAttributesConfigRequest {
    /// Required. Full AttributesConfig resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetAttributesConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetAttributesConfigRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for GetAttributesConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetAttributesConfigRequest"
    }
}

/// Request for
/// [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.UpdateAttributesConfig]: crate::client::CatalogService::update_attributes_config
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateAttributesConfigRequest {
    /// Required. The [AttributesConfig][google.cloud.retail.v2.AttributesConfig]
    /// to update.
    ///
    /// [google.cloud.retail.v2.AttributesConfig]: crate::model::AttributesConfig
    pub attributes_config: std::option::Option<crate::model::AttributesConfig>,

    /// Indicates which fields in the provided
    /// [AttributesConfig][google.cloud.retail.v2.AttributesConfig] to update. The
    /// following is the only supported field:
    ///
    /// * [AttributesConfig.catalog_attributes][google.cloud.retail.v2.AttributesConfig.catalog_attributes]
    ///
    /// If not set, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.AttributesConfig]: crate::model::AttributesConfig
    /// [google.cloud.retail.v2.AttributesConfig.catalog_attributes]: crate::model::AttributesConfig::catalog_attributes
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateAttributesConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [attributes_config][crate::model::UpdateAttributesConfigRequest::attributes_config].
    pub fn set_attributes_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AttributesConfig>,
    {
        self.attributes_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [attributes_config][crate::model::UpdateAttributesConfigRequest::attributes_config].
    pub fn set_or_clear_attributes_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AttributesConfig>,
    {
        self.attributes_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateAttributesConfigRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateAttributesConfigRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateAttributesConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateAttributesConfigRequest"
    }
}

/// Request for
/// [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.AddCatalogAttribute]: crate::client::CatalogService::add_catalog_attribute
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddCatalogAttributeRequest {
    /// Required. Full AttributesConfig resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
    pub attributes_config: std::string::String,

    /// Required. The [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute]
    /// to add.
    ///
    /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
    pub catalog_attribute: std::option::Option<crate::model::CatalogAttribute>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddCatalogAttributeRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [attributes_config][crate::model::AddCatalogAttributeRequest::attributes_config].
    pub fn set_attributes_config<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attributes_config = v.into();
        self
    }

    /// Sets the value of [catalog_attribute][crate::model::AddCatalogAttributeRequest::catalog_attribute].
    pub fn set_catalog_attribute<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CatalogAttribute>,
    {
        self.catalog_attribute = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [catalog_attribute][crate::model::AddCatalogAttributeRequest::catalog_attribute].
    pub fn set_or_clear_catalog_attribute<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CatalogAttribute>,
    {
        self.catalog_attribute = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for AddCatalogAttributeRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddCatalogAttributeRequest"
    }
}

/// Request for
/// [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute]: crate::client::CatalogService::remove_catalog_attribute
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveCatalogAttributeRequest {
    /// Required. Full AttributesConfig resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
    pub attributes_config: std::string::String,

    /// Required. The attribute name key of the
    /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to remove.
    ///
    /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
    pub key: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveCatalogAttributeRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [attributes_config][crate::model::RemoveCatalogAttributeRequest::attributes_config].
    pub fn set_attributes_config<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attributes_config = v.into();
        self
    }

    /// Sets the value of [key][crate::model::RemoveCatalogAttributeRequest::key].
    pub fn set_key<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.key = v.into();
        self
    }
}

impl wkt::message::Message for RemoveCatalogAttributeRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveCatalogAttributeRequest"
    }
}

/// Request for
/// [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute]
/// method.
///
/// [google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute]: crate::client::CatalogService::replace_catalog_attribute
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ReplaceCatalogAttributeRequest {
    /// Required. Full AttributesConfig resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
    pub attributes_config: std::string::String,

    /// Required. The updated
    /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute].
    ///
    /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
    pub catalog_attribute: std::option::Option<crate::model::CatalogAttribute>,

    /// Indicates which fields in the provided
    /// [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to update. The
    /// following are NOT supported:
    ///
    /// * [CatalogAttribute.key][google.cloud.retail.v2.CatalogAttribute.key]
    ///
    /// If not set, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
    /// [google.cloud.retail.v2.CatalogAttribute.key]: crate::model::CatalogAttribute::key
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ReplaceCatalogAttributeRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [attributes_config][crate::model::ReplaceCatalogAttributeRequest::attributes_config].
    pub fn set_attributes_config<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attributes_config = v.into();
        self
    }

    /// Sets the value of [catalog_attribute][crate::model::ReplaceCatalogAttributeRequest::catalog_attribute].
    pub fn set_catalog_attribute<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CatalogAttribute>,
    {
        self.catalog_attribute = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [catalog_attribute][crate::model::ReplaceCatalogAttributeRequest::catalog_attribute].
    pub fn set_or_clear_catalog_attribute<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CatalogAttribute>,
    {
        self.catalog_attribute = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::ReplaceCatalogAttributeRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::ReplaceCatalogAttributeRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ReplaceCatalogAttributeRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ReplaceCatalogAttributeRequest"
    }
}

/// Metadata that is used to define a condition that triggers an action.
/// A valid condition must specify at least one of 'query_terms' or
/// 'products_filter'. If multiple fields are specified, the condition is met if
/// all the fields are satisfied e.g. if a set of query terms and product_filter
/// are set, then only items matching the product_filter for requests with a
/// query matching the query terms wil get boosted.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Condition {
    /// A list (up to 10 entries) of terms to match the query on. If not
    /// specified, match all queries.
    /// If many query terms are specified, the condition
    /// is matched if any of the terms is a match (i.e. using the OR operator).
    pub query_terms: std::vec::Vec<crate::model::condition::QueryTerm>,

    /// Range of time(s) specifying when Condition is active.
    /// Condition true if any time range matches.
    pub active_time_range: std::vec::Vec<crate::model::condition::TimeRange>,

    /// Used to support browse uses cases.
    /// A list (up to 10 entries) of categories or departments.
    /// The format should be the same as
    /// [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories];
    ///
    /// [google.cloud.retail.v2.UserEvent.page_categories]: crate::model::UserEvent::page_categories
    pub page_categories: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Condition {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [query_terms][crate::model::Condition::query_terms].
    pub fn set_query_terms<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::condition::QueryTerm>,
    {
        use std::iter::Iterator;
        self.query_terms = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [active_time_range][crate::model::Condition::active_time_range].
    pub fn set_active_time_range<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::condition::TimeRange>,
    {
        use std::iter::Iterator;
        self.active_time_range = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [page_categories][crate::model::Condition::page_categories].
    pub fn set_page_categories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.page_categories = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for Condition {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Condition"
    }
}

/// Defines additional types related to [Condition].
pub mod condition {
    #[allow(unused_imports)]
    use super::*;

    /// Query terms that we want to match on.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct QueryTerm {
        /// The value of the term to match on.
        /// Value cannot be empty.
        /// Value can have at most 3 terms if specified as a partial match. Each
        /// space separated string is considered as one term.
        /// For example, "a b c" is 3 terms and allowed, but " a b c d" is 4 terms
        /// and not allowed for a partial match.
        pub value: std::string::String,

        /// Whether this is supposed to be a full or partial match.
        pub full_match: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl QueryTerm {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [value][crate::model::condition::QueryTerm::value].
        pub fn set_value<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.value = v.into();
            self
        }

        /// Sets the value of [full_match][crate::model::condition::QueryTerm::full_match].
        pub fn set_full_match<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.full_match = v.into();
            self
        }
    }

    impl wkt::message::Message for QueryTerm {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Condition.QueryTerm"
        }
    }

    /// Used for time-dependent conditions.
    /// Example: Want to have rule applied for week long sale.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct TimeRange {
        /// Start of time range. Range is inclusive.
        pub start_time: std::option::Option<wkt::Timestamp>,

        /// End of time range. Range is inclusive.
        pub end_time: std::option::Option<wkt::Timestamp>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl TimeRange {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [start_time][crate::model::condition::TimeRange::start_time].
        pub fn set_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [start_time][crate::model::condition::TimeRange::start_time].
        pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [end_time][crate::model::condition::TimeRange::end_time].
        pub fn set_end_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.end_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [end_time][crate::model::condition::TimeRange::end_time].
        pub fn set_or_clear_end_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.end_time = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for TimeRange {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Condition.TimeRange"
        }
    }
}

/// A rule is a condition-action pair
///
/// * A condition defines when a rule is to be triggered.
/// * An action specifies what occurs on that trigger.
///   Currently rules only work for [controls][google.cloud.retail.v2.Control] with
///   [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
///
/// [google.cloud.retail.v2.Control]: crate::model::Control
/// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Rule {
    /// Required. The condition that triggers the rule.
    /// If the condition is empty, the rule will always apply.
    pub condition: std::option::Option<crate::model::Condition>,

    /// An action must be provided.
    pub action: std::option::Option<crate::model::rule::Action>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Rule {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [condition][crate::model::Rule::condition].
    pub fn set_condition<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Condition>,
    {
        self.condition = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition][crate::model::Rule::condition].
    pub fn set_or_clear_condition<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Condition>,
    {
        self.condition = v.map(|x| x.into());
        self
    }

    /// Sets the value of [action][crate::model::Rule::action].
    ///
    /// Note that all the setters affecting `action` are mutually
    /// exclusive.
    pub fn set_action<T: std::convert::Into<std::option::Option<crate::model::rule::Action>>>(
        mut self,
        v: T,
    ) -> Self {
        self.action = v.into();
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `BoostAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn boost_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::BoostAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::BoostAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `BoostAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_boost_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::BoostAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action = std::option::Option::Some(crate::model::rule::Action::BoostAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `RedirectAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn redirect_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::RedirectAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::RedirectAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `RedirectAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_redirect_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::RedirectAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::RedirectAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `OnewaySynonymsAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn oneway_synonyms_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::OnewaySynonymsAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::OnewaySynonymsAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `OnewaySynonymsAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_oneway_synonyms_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::OnewaySynonymsAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::OnewaySynonymsAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `DoNotAssociateAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn do_not_associate_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::DoNotAssociateAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::DoNotAssociateAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `DoNotAssociateAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_do_not_associate_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::DoNotAssociateAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::DoNotAssociateAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `ReplacementAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn replacement_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::ReplacementAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::ReplacementAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `ReplacementAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_replacement_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::ReplacementAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::ReplacementAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `IgnoreAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn ignore_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::IgnoreAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::IgnoreAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `IgnoreAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_ignore_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::IgnoreAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action = std::option::Option::Some(crate::model::rule::Action::IgnoreAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `FilterAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn filter_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::FilterAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::FilterAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `FilterAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_filter_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::FilterAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action = std::option::Option::Some(crate::model::rule::Action::FilterAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `TwowaySynonymsAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn twoway_synonyms_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::TwowaySynonymsAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::TwowaySynonymsAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `TwowaySynonymsAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_twoway_synonyms_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::TwowaySynonymsAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::TwowaySynonymsAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `ForceReturnFacetAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn force_return_facet_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::ForceReturnFacetAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::ForceReturnFacetAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `ForceReturnFacetAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_force_return_facet_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::ForceReturnFacetAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::ForceReturnFacetAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `RemoveFacetAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn remove_facet_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::RemoveFacetAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::RemoveFacetAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `RemoveFacetAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_remove_facet_action<
        T: std::convert::Into<std::boxed::Box<crate::model::rule::RemoveFacetAction>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.action =
            std::option::Option::Some(crate::model::rule::Action::RemoveFacetAction(v.into()));
        self
    }

    /// The value of [action][crate::model::Rule::action]
    /// if it holds a `PinAction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn pin_action(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::rule::PinAction>> {
        #[allow(unreachable_patterns)]
        self.action.as_ref().and_then(|v| match v {
            crate::model::rule::Action::PinAction(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [action][crate::model::Rule::action]
    /// to hold a `PinAction`.
    ///
    /// Note that all the setters affecting `action` are
    /// mutually exclusive.
    pub fn set_pin_action<T: std::convert::Into<std::boxed::Box<crate::model::rule::PinAction>>>(
        mut self,
        v: T,
    ) -> Self {
        self.action = std::option::Option::Some(crate::model::rule::Action::PinAction(v.into()));
        self
    }
}

impl wkt::message::Message for Rule {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Rule"
    }
}

/// Defines additional types related to [Rule].
pub mod rule {
    #[allow(unused_imports)]
    use super::*;

    /// A boost action to apply to results matching condition specified above.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct BoostAction {
        /// Strength of the condition boost, which must be in [-1, 1]. Negative
        /// boost means demotion. Default is 0.0.
        ///
        /// Setting to 1.0 gives the item a big promotion. However, it does not
        /// necessarily mean that the boosted item will be the top result at all
        /// times, nor that other items will be excluded. Results could still be
        /// shown even when none of them matches the condition. And results that
        /// are significantly more relevant to the search query can still trump
        /// your heavily favored but irrelevant items.
        ///
        /// Setting to -1.0 gives the item a big demotion. However, results that
        /// are deeply relevant might still be shown. The item will have an
        /// upstream battle to get a fairly high ranking, but it is not blocked out
        /// completely.
        ///
        /// Setting to 0.0 means no boost applied. The boosting condition is
        /// ignored.
        pub boost: f32,

        /// The filter can have a max size of 5000 characters.
        /// An expression which specifies which products to apply an action to.
        /// The syntax and supported fields are the same as a filter expression. See
        /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
        /// detail syntax and limitations.
        ///
        /// Examples:
        ///
        /// * To boost products with product ID "product_1" or "product_2", and
        ///   color
        ///   "Red" or "Blue":\<br\>
        ///   *(id: ANY("product_1", "product_2"))<br>*
        ///   *AND<br>*
        ///   *(colorFamilies: ANY("Red", "Blue"))<br>*
        ///
        /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
        pub products_filter: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl BoostAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [boost][crate::model::rule::BoostAction::boost].
        pub fn set_boost<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
            self.boost = v.into();
            self
        }

        /// Sets the value of [products_filter][crate::model::rule::BoostAction::products_filter].
        pub fn set_products_filter<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.products_filter = v.into();
            self
        }
    }

    impl wkt::message::Message for BoostAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.BoostAction"
        }
    }

    /// * Rule Condition:
    ///
    ///   - No
    ///     [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms]
    ///     provided is a global match.
    ///   - 1 or more
    ///     [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms]
    ///     provided are combined with OR operator.
    /// * Action Input: The request query and filter that are applied to the
    ///   retrieved products, in addition to any filters already provided with the
    ///   SearchRequest. The AND operator is used to combine the query's existing
    ///   filters with the filter rule(s). NOTE: May result in 0 results when
    ///   filters conflict.
    ///
    /// * Action Result: Filters the returned objects to be ONLY those that passed
    ///   the filter.
    ///
    ///
    /// [google.cloud.retail.v2.Condition.query_terms]: crate::model::Condition::query_terms
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FilterAction {
        /// A filter to apply on the matching condition results. Supported features:
        ///
        /// * [filter][google.cloud.retail.v2.Rule.FilterAction.filter] must be set.
        /// * Filter syntax is identical to
        ///   [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter]. For
        ///   more
        ///   information, see [Filter](/retail/docs/filter-and-order#filter).
        /// * To filter products with product ID "product_1" or "product_2", and
        ///   color
        ///   "Red" or "Blue":\<br\>
        ///   *(id: ANY("product_1", "product_2"))<br>*
        ///   *AND<br>*
        ///   *(colorFamilies: ANY("Red", "Blue"))<br>*
        ///
        /// [google.cloud.retail.v2.Rule.FilterAction.filter]: crate::model::rule::FilterAction::filter
        /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
        pub filter: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FilterAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [filter][crate::model::rule::FilterAction::filter].
        pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.filter = v.into();
            self
        }
    }

    impl wkt::message::Message for FilterAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.FilterAction"
        }
    }

    /// Redirects a shopper to a specific page.
    ///
    /// * Rule Condition:
    ///   Must specify
    ///   [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms].
    /// * Action Input: Request Query
    /// * Action Result: Redirects shopper to provided uri.
    ///
    /// [google.cloud.retail.v2.Condition.query_terms]: crate::model::Condition::query_terms
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct RedirectAction {
        /// URL must have length equal or less than 2000 characters.
        pub redirect_uri: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl RedirectAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [redirect_uri][crate::model::rule::RedirectAction::redirect_uri].
        pub fn set_redirect_uri<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.redirect_uri = v.into();
            self
        }
    }

    impl wkt::message::Message for RedirectAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.RedirectAction"
        }
    }

    /// Creates a set of terms that will be treated as synonyms of each other.
    /// Example: synonyms of "sneakers" and "shoes":
    ///
    /// * "sneakers" will use a synonym of "shoes".
    /// * "shoes" will use a synonym of "sneakers".
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct TwowaySynonymsAction {
        /// Defines a set of synonyms.
        /// Can specify up to 100 synonyms.
        /// Must specify at least 2 synonyms.
        pub synonyms: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl TwowaySynonymsAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [synonyms][crate::model::rule::TwowaySynonymsAction::synonyms].
        pub fn set_synonyms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.synonyms = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for TwowaySynonymsAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.TwowaySynonymsAction"
        }
    }

    /// Maps a set of terms to a set of synonyms.
    /// Set of synonyms will be treated as synonyms of each query term only.
    /// `query_terms` will not be treated as synonyms of each other.
    /// Example: "sneakers" will use a synonym of "shoes".
    /// "shoes" will not use a synonym of "sneakers".
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct OnewaySynonymsAction {
        /// Terms from the search query.
        /// Will treat synonyms as their synonyms.
        /// Not themselves synonyms of the synonyms.
        /// Can specify up to 100 terms.
        pub query_terms: std::vec::Vec<std::string::String>,

        /// Defines a set of synonyms.
        /// Cannot contain duplicates.
        /// Can specify up to 100 synonyms.
        pub synonyms: std::vec::Vec<std::string::String>,

        /// Will be [deprecated = true] post migration;
        pub oneway_terms: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl OnewaySynonymsAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [query_terms][crate::model::rule::OnewaySynonymsAction::query_terms].
        pub fn set_query_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.query_terms = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [synonyms][crate::model::rule::OnewaySynonymsAction::synonyms].
        pub fn set_synonyms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.synonyms = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [oneway_terms][crate::model::rule::OnewaySynonymsAction::oneway_terms].
        pub fn set_oneway_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.oneway_terms = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for OnewaySynonymsAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.OnewaySynonymsAction"
        }
    }

    /// Prevents `query_term` from being associated with specified terms during
    /// search.
    /// Example: Don't associate "gShoe" and "cheap".
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct DoNotAssociateAction {
        /// Terms from the search query.
        /// Will not consider do_not_associate_terms for search if in search query.
        /// Can specify up to 100 terms.
        pub query_terms: std::vec::Vec<std::string::String>,

        /// Cannot contain duplicates or the query term.
        /// Can specify up to 100 terms.
        pub do_not_associate_terms: std::vec::Vec<std::string::String>,

        /// Will be [deprecated = true] post migration;
        pub terms: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl DoNotAssociateAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [query_terms][crate::model::rule::DoNotAssociateAction::query_terms].
        pub fn set_query_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.query_terms = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [do_not_associate_terms][crate::model::rule::DoNotAssociateAction::do_not_associate_terms].
        pub fn set_do_not_associate_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.do_not_associate_terms = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [terms][crate::model::rule::DoNotAssociateAction::terms].
        pub fn set_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.terms = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for DoNotAssociateAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.DoNotAssociateAction"
        }
    }

    /// Replaces a term in the query. Multiple replacement candidates can be
    /// specified. All `query_terms` will be replaced with the replacement term.
    /// Example: Replace "gShoe" with "google shoe".
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ReplacementAction {
        /// Terms from the search query.
        /// Will be replaced by replacement term.
        /// Can specify up to 100 terms.
        pub query_terms: std::vec::Vec<std::string::String>,

        /// Term that will be used for replacement.
        pub replacement_term: std::string::String,

        /// Will be [deprecated = true] post migration;
        pub term: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ReplacementAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [query_terms][crate::model::rule::ReplacementAction::query_terms].
        pub fn set_query_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.query_terms = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [replacement_term][crate::model::rule::ReplacementAction::replacement_term].
        pub fn set_replacement_term<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.replacement_term = v.into();
            self
        }

        /// Sets the value of [term][crate::model::rule::ReplacementAction::term].
        pub fn set_term<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.term = v.into();
            self
        }
    }

    impl wkt::message::Message for ReplacementAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.ReplacementAction"
        }
    }

    /// Prevents a term in the query from being used in search.
    /// Example: Don't search for "shoddy".
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct IgnoreAction {
        /// Terms to ignore in the search query.
        pub ignore_terms: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl IgnoreAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [ignore_terms][crate::model::rule::IgnoreAction::ignore_terms].
        pub fn set_ignore_terms<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.ignore_terms = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for IgnoreAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.IgnoreAction"
        }
    }

    /// Force returns an attribute/facet in the request around a certain position
    /// or above.
    ///
    /// * Rule Condition:
    ///   Must specify non-empty
    ///   [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms]
    ///   (for search only) or
    ///   [Condition.page_categories][google.cloud.retail.v2.Condition.page_categories]
    ///   (for browse only), but can't specify both.
    ///
    /// * Action Inputs: attribute name, position
    ///
    /// * Action Result: Will force return a facet key around a certain position
    ///   or above if the condition is satisfied.
    ///
    ///
    /// Example: Suppose the query is "shoes", the
    /// [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms] is
    /// "shoes", the
    /// [ForceReturnFacetAction.FacetPositionAdjustment.attribute_name][google.cloud.retail.v2.Rule.ForceReturnFacetAction.FacetPositionAdjustment.attribute_name]
    /// is "size" and the
    /// [ForceReturnFacetAction.FacetPositionAdjustment.position][google.cloud.retail.v2.Rule.ForceReturnFacetAction.FacetPositionAdjustment.position]
    /// is 8.
    ///
    /// Two cases: a) The facet key "size" is not already in the top 8 slots, then
    /// the facet "size" will appear at a position close to 8. b) The facet key
    /// "size" in among the top 8 positions in the request, then it will stay at
    /// its current rank.
    ///
    /// [google.cloud.retail.v2.Condition.page_categories]: crate::model::Condition::page_categories
    /// [google.cloud.retail.v2.Condition.query_terms]: crate::model::Condition::query_terms
    /// [google.cloud.retail.v2.Rule.ForceReturnFacetAction.FacetPositionAdjustment.attribute_name]: crate::model::rule::force_return_facet_action::FacetPositionAdjustment::attribute_name
    /// [google.cloud.retail.v2.Rule.ForceReturnFacetAction.FacetPositionAdjustment.position]: crate::model::rule::force_return_facet_action::FacetPositionAdjustment::position
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ForceReturnFacetAction {
        /// Each instance corresponds to a force return attribute for the given
        /// condition. There can't be more 15 instances here.
        pub facet_position_adjustments:
            std::vec::Vec<crate::model::rule::force_return_facet_action::FacetPositionAdjustment>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ForceReturnFacetAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [facet_position_adjustments][crate::model::rule::ForceReturnFacetAction::facet_position_adjustments].
        pub fn set_facet_position_adjustments<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<
                    crate::model::rule::force_return_facet_action::FacetPositionAdjustment,
                >,
        {
            use std::iter::Iterator;
            self.facet_position_adjustments = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for ForceReturnFacetAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.ForceReturnFacetAction"
        }
    }

    /// Defines additional types related to [ForceReturnFacetAction].
    pub mod force_return_facet_action {
        #[allow(unused_imports)]
        use super::*;

        /// Each facet position adjustment consists of a single attribute name (i.e.
        /// facet key) along with a specified position.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct FacetPositionAdjustment {
            /// The attribute name to force return as a facet. Each attribute name
            /// should be a valid attribute name, be non-empty and contain at most 80
            /// characters long.
            pub attribute_name: std::string::String,

            /// This is the position in the request as explained above. It should be
            /// strictly positive be at most 100.
            pub position: i32,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl FacetPositionAdjustment {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [attribute_name][crate::model::rule::force_return_facet_action::FacetPositionAdjustment::attribute_name].
            pub fn set_attribute_name<T: std::convert::Into<std::string::String>>(
                mut self,
                v: T,
            ) -> Self {
                self.attribute_name = v.into();
                self
            }

            /// Sets the value of [position][crate::model::rule::force_return_facet_action::FacetPositionAdjustment::position].
            pub fn set_position<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
                self.position = v.into();
                self
            }
        }

        impl wkt::message::Message for FacetPositionAdjustment {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.Rule.ForceReturnFacetAction.FacetPositionAdjustment"
            }
        }
    }

    /// Removes an attribute/facet in the request if is present.
    ///
    /// * Rule Condition:
    ///   Must specify non-empty
    ///   [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms]
    ///   (for search only) or
    ///   [Condition.page_categories][google.cloud.retail.v2.Condition.page_categories]
    ///   (for browse only), but can't specify both.
    ///
    /// * Action Input: attribute name
    ///
    /// * Action Result: Will remove the attribute (as a facet) from the request
    ///   if it is present.
    ///
    ///
    /// Example: Suppose the query is "shoes", the
    /// [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms] is
    /// "shoes" and the attribute name "size", then facet key "size" will be
    /// removed from the request (if it is present).
    ///
    /// [google.cloud.retail.v2.Condition.page_categories]: crate::model::Condition::page_categories
    /// [google.cloud.retail.v2.Condition.query_terms]: crate::model::Condition::query_terms
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct RemoveFacetAction {
        /// The attribute names (i.e. facet keys) to remove from the dynamic facets
        /// (if present in the request). There can't be more 3 attribute names.
        /// Each attribute name should be a valid attribute name, be non-empty and
        /// contain at most 80 characters.
        pub attribute_names: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl RemoveFacetAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [attribute_names][crate::model::rule::RemoveFacetAction::attribute_names].
        pub fn set_attribute_names<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.attribute_names = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for RemoveFacetAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.RemoveFacetAction"
        }
    }

    /// Pins one or more specified products to a specific position in the
    /// results.
    ///
    /// * Rule Condition:
    ///   Must specify non-empty
    ///   [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms]
    ///   (for search only) or
    ///   [Condition.page_categories][google.cloud.retail.v2.Condition.page_categories]
    ///   (for browse only), but can't specify both.
    ///
    /// * Action Input: mapping of `[pin_position, product_id]` pairs (pin position
    ///   uses 1-based indexing).
    ///
    /// * Action Result: Will pin products with matching ids to the position
    ///   specified in the final result order.
    ///
    ///
    /// Example: Suppose the query is `shoes`, the
    /// [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms] is
    /// `shoes` and the pin_map has `{1, "pid1"}`, then product with `pid1` will be
    /// pinned to the top position in the final results.
    ///
    /// If multiple PinActions are matched to a single request the actions will
    /// be processed from most to least recently updated.
    ///
    /// Pins to positions larger than the max allowed page size of 120 are not
    /// allowed.
    ///
    /// [google.cloud.retail.v2.Condition.page_categories]: crate::model::Condition::page_categories
    /// [google.cloud.retail.v2.Condition.query_terms]: crate::model::Condition::query_terms
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct PinAction {
        /// Required. A map of positions to product_ids.
        ///
        /// Partial matches per action are allowed, if a certain position in the map
        /// is already filled that `[position, product_id]` pair will be ignored
        /// but the rest may still be applied. This case will only occur if multiple
        /// pin actions are matched to a single request, as the map guarantees that
        /// pin positions are unique within the same action.
        ///
        /// Duplicate product_ids are not permitted within a single pin map.
        ///
        /// The max size of this map is 120, equivalent to the max [request page
        /// size](https://cloud.google.com/retail/docs/reference/rest/v2/projects.locations.catalogs.placements/search#request-body).
        pub pin_map: std::collections::HashMap<i64, std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl PinAction {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [pin_map][crate::model::rule::PinAction::pin_map].
        pub fn set_pin_map<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<i64>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.pin_map = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }
    }

    impl wkt::message::Message for PinAction {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Rule.PinAction"
        }
    }

    /// An action must be provided.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Action {
        /// A boost action.
        BoostAction(std::boxed::Box<crate::model::rule::BoostAction>),
        /// Redirects a shopper to a specific page.
        RedirectAction(std::boxed::Box<crate::model::rule::RedirectAction>),
        /// Treats specific term as a synonym with a group of terms.
        /// Group of terms will not be treated as synonyms with the specific term.
        OnewaySynonymsAction(std::boxed::Box<crate::model::rule::OnewaySynonymsAction>),
        /// Prevents term from being associated with other terms.
        DoNotAssociateAction(std::boxed::Box<crate::model::rule::DoNotAssociateAction>),
        /// Replaces specific terms in the query.
        ReplacementAction(std::boxed::Box<crate::model::rule::ReplacementAction>),
        /// Ignores specific terms from query during search.
        IgnoreAction(std::boxed::Box<crate::model::rule::IgnoreAction>),
        /// Filters results.
        FilterAction(std::boxed::Box<crate::model::rule::FilterAction>),
        /// Treats a set of terms as synonyms of one another.
        TwowaySynonymsAction(std::boxed::Box<crate::model::rule::TwowaySynonymsAction>),
        /// Force returns an attribute as a facet in the request.
        ForceReturnFacetAction(std::boxed::Box<crate::model::rule::ForceReturnFacetAction>),
        /// Remove an attribute as a facet in the request (if present).
        RemoveFacetAction(std::boxed::Box<crate::model::rule::RemoveFacetAction>),
        /// Pins one or more specified products to a specific position in the
        /// results.
        PinAction(std::boxed::Box<crate::model::rule::PinAction>),
    }
}

/// An intended audience of the [Product][google.cloud.retail.v2.Product] for
/// whom it's sold.
///
/// [google.cloud.retail.v2.Product]: crate::model::Product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Audience {
    /// The genders of the audience. Strongly encouraged to use the standard
    /// values: "male", "female", "unisex".
    ///
    /// At most 5 values are allowed. Each value must be a UTF-8 encoded string
    /// with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error
    /// is returned.
    ///
    /// Google Merchant Center property
    /// [gender](https://support.google.com/merchants/answer/6324479). Schema.org
    /// property
    /// [Product.audience.suggestedGender](https://schema.org/suggestedGender).
    pub genders: std::vec::Vec<std::string::String>,

    /// The age groups of the audience. Strongly encouraged to use the standard
    /// values: "newborn" (up to 3 months old), "infant" (3–12 months old),
    /// "toddler" (1–5 years old), "kids" (5–13 years old), "adult" (typically
    /// teens or older).
    ///
    /// At most 5 values are allowed. Each value must be a UTF-8 encoded string
    /// with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error
    /// is returned.
    ///
    /// Google Merchant Center property
    /// [age_group](https://support.google.com/merchants/answer/6324463).
    /// Schema.org property
    /// [Product.audience.suggestedMinAge](https://schema.org/suggestedMinAge) and
    /// [Product.audience.suggestedMaxAge](https://schema.org/suggestedMaxAge).
    pub age_groups: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Audience {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [genders][crate::model::Audience::genders].
    pub fn set_genders<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.genders = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [age_groups][crate::model::Audience::age_groups].
    pub fn set_age_groups<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.age_groups = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for Audience {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Audience"
    }
}

/// The color information of a [Product][google.cloud.retail.v2.Product].
///
/// [google.cloud.retail.v2.Product]: crate::model::Product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ColorInfo {
    /// The standard color families. Strongly recommended to use the following
    /// standard color groups: "Red", "Pink", "Orange", "Yellow", "Purple",
    /// "Green", "Cyan", "Blue", "Brown", "White", "Gray", "Black" and "Mixed".
    /// Normally it is expected to have only 1 color family. May consider using
    /// single "Mixed" instead of multiple values.
    ///
    /// A maximum of 5 values are allowed. Each value must be a UTF-8 encoded
    /// string with a length limit of 128 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Google Merchant Center property
    /// [color](https://support.google.com/merchants/answer/6324487). Schema.org
    /// property [Product.color](https://schema.org/color).
    ///
    /// The colorFamilies field as a system attribute is not a required field but
    /// strongly recommended to be specified. Google Search models treat this field
    /// as more important than a custom product attribute when specified.
    pub color_families: std::vec::Vec<std::string::String>,

    /// The color display names, which may be different from standard color family
    /// names, such as the color aliases used in the website frontend. Normally
    /// it is expected to have only 1 color. May consider using single "Mixed"
    /// instead of multiple values.
    ///
    /// A maximum of 75 colors are allowed. Each value must be a UTF-8 encoded
    /// string with a length limit of 128 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Google Merchant Center property
    /// [color](https://support.google.com/merchants/answer/6324487). Schema.org
    /// property [Product.color](https://schema.org/color).
    pub colors: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ColorInfo {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [color_families][crate::model::ColorInfo::color_families].
    pub fn set_color_families<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.color_families = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [colors][crate::model::ColorInfo::colors].
    pub fn set_colors<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.colors = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ColorInfo {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ColorInfo"
    }
}

/// A custom attribute that is not explicitly modeled in
/// [Product][google.cloud.retail.v2.Product].
///
/// [google.cloud.retail.v2.Product]: crate::model::Product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CustomAttribute {
    /// The textual values of this custom attribute. For example, `["yellow",
    /// "green"]` when the key is "color".
    ///
    /// Empty string is not allowed. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    ///
    /// Exactly one of [text][google.cloud.retail.v2.CustomAttribute.text] or
    /// [numbers][google.cloud.retail.v2.CustomAttribute.numbers] should be set.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.CustomAttribute.numbers]: crate::model::CustomAttribute::numbers
    /// [google.cloud.retail.v2.CustomAttribute.text]: crate::model::CustomAttribute::text
    pub text: std::vec::Vec<std::string::String>,

    /// The numerical values of this custom attribute. For example, `[2.3, 15.4]`
    /// when the key is "lengths_cm".
    ///
    /// Exactly one of [text][google.cloud.retail.v2.CustomAttribute.text] or
    /// [numbers][google.cloud.retail.v2.CustomAttribute.numbers] should be set.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.CustomAttribute.numbers]: crate::model::CustomAttribute::numbers
    /// [google.cloud.retail.v2.CustomAttribute.text]: crate::model::CustomAttribute::text
    pub numbers: std::vec::Vec<f64>,

    /// This field is normally ignored unless
    /// [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level]
    /// of the [Catalog][google.cloud.retail.v2.Catalog] is set to the deprecated
    /// 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For information about product-level
    /// attribute configuration, see [Configuration
    /// modes](https://cloud.google.com/retail/docs/attribute-config#config-modes).
    /// If true, custom attribute values are searchable by text queries in
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search].
    ///
    /// This field is ignored in a [UserEvent][google.cloud.retail.v2.UserEvent].
    ///
    /// Only set if type [text][google.cloud.retail.v2.CustomAttribute.text] is
    /// set. Otherwise, a INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.AttributesConfig.attribute_config_level]: crate::model::AttributesConfig::attribute_config_level
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    /// [google.cloud.retail.v2.CustomAttribute.text]: crate::model::CustomAttribute::text
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    #[deprecated]
    pub searchable: std::option::Option<bool>,

    /// This field is normally ignored unless
    /// [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level]
    /// of the [Catalog][google.cloud.retail.v2.Catalog] is set to the deprecated
    /// 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For information about product-level
    /// attribute configuration, see [Configuration
    /// modes](https://cloud.google.com/retail/docs/attribute-config#config-modes).
    /// If true, custom attribute values are indexed, so that they can be filtered,
    /// faceted or boosted in
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search].
    ///
    /// This field is ignored in a [UserEvent][google.cloud.retail.v2.UserEvent].
    ///
    /// See [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter],
    /// [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs]
    /// and
    /// [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec]
    /// for more details.
    ///
    /// [google.cloud.retail.v2.AttributesConfig.attribute_config_level]: crate::model::AttributesConfig::attribute_config_level
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    /// [google.cloud.retail.v2.SearchRequest.boost_spec]: crate::model::SearchRequest::boost_spec
    /// [google.cloud.retail.v2.SearchRequest.facet_specs]: crate::model::SearchRequest::facet_specs
    /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    #[deprecated]
    pub indexable: std::option::Option<bool>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CustomAttribute {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [text][crate::model::CustomAttribute::text].
    pub fn set_text<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.text = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [numbers][crate::model::CustomAttribute::numbers].
    pub fn set_numbers<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<f64>,
    {
        use std::iter::Iterator;
        self.numbers = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [searchable][crate::model::CustomAttribute::searchable].
    #[deprecated]
    pub fn set_searchable<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<bool>,
    {
        self.searchable = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [searchable][crate::model::CustomAttribute::searchable].
    #[deprecated]
    pub fn set_or_clear_searchable<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<bool>,
    {
        self.searchable = v.map(|x| x.into());
        self
    }

    /// Sets the value of [indexable][crate::model::CustomAttribute::indexable].
    #[deprecated]
    pub fn set_indexable<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<bool>,
    {
        self.indexable = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [indexable][crate::model::CustomAttribute::indexable].
    #[deprecated]
    pub fn set_or_clear_indexable<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<bool>,
    {
        self.indexable = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for CustomAttribute {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CustomAttribute"
    }
}

/// Fulfillment information, such as the store IDs for in-store pickup or region
/// IDs for different shipping methods.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct FulfillmentInfo {
    /// The fulfillment type, including commonly used types (such as pickup in
    /// store and same day delivery), and custom types. Customers have to map
    /// custom types to their display names before rendering UI.
    ///
    /// Supported values:
    ///
    /// * "pickup-in-store"
    /// * "ship-to-store"
    /// * "same-day-delivery"
    /// * "next-day-delivery"
    /// * "custom-type-1"
    /// * "custom-type-2"
    /// * "custom-type-3"
    /// * "custom-type-4"
    /// * "custom-type-5"
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    pub r#type: std::string::String,

    /// The IDs for this [type][google.cloud.retail.v2.FulfillmentInfo.type], such
    /// as the store IDs for
    /// [FulfillmentInfo.type.pickup-in-store][google.cloud.retail.v2.FulfillmentInfo.type]
    /// or the region IDs for
    /// [FulfillmentInfo.type.same-day-delivery][google.cloud.retail.v2.FulfillmentInfo.type].
    ///
    /// A maximum of 3000 values are allowed. Each value must be a string with a
    /// length limit of 30 characters, matching the pattern `[a-zA-Z0-9_-]+`, such
    /// as "store1" or "REGION-2". Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    ///
    /// [google.cloud.retail.v2.FulfillmentInfo.type]: crate::model::FulfillmentInfo::type
    pub place_ids: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl FulfillmentInfo {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [r#type][crate::model::FulfillmentInfo::type].
    pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [place_ids][crate::model::FulfillmentInfo::place_ids].
    pub fn set_place_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.place_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for FulfillmentInfo {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.FulfillmentInfo"
    }
}

/// [Product][google.cloud.retail.v2.Product] image. Recommendations AI and
/// Retail Search use product images to improve prediction and search results.
/// Product images can be returned in results, and are shown in prediction or
/// search previews in the console. Please try to provide correct product images
/// and avoid using images with size too small.
///
/// [google.cloud.retail.v2.Product]: crate::model::Product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Image {
    /// Required. URI of the image.
    ///
    /// This field must be a valid UTF-8 encoded URI with a length limit of 5,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Google Merchant Center property
    /// [image_link](https://support.google.com/merchants/answer/6324350).
    /// Schema.org property [Product.image](https://schema.org/image).
    pub uri: std::string::String,

    /// Height of the image in number of pixels.
    ///
    /// This field must be nonnegative. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    pub height: i32,

    /// Width of the image in number of pixels.
    ///
    /// This field must be nonnegative. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    pub width: i32,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Image {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [uri][crate::model::Image::uri].
    pub fn set_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.uri = v.into();
        self
    }

    /// Sets the value of [height][crate::model::Image::height].
    pub fn set_height<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.height = v.into();
        self
    }

    /// Sets the value of [width][crate::model::Image::width].
    pub fn set_width<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.width = v.into();
        self
    }
}

impl wkt::message::Message for Image {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Image"
    }
}

/// A floating point interval.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Interval {
    /// The lower bound of the interval. If neither of the min fields are set, then
    /// the lower bound is negative infinity.
    ///
    /// This field must not be larger than max.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    pub min: std::option::Option<crate::model::interval::Min>,

    /// The upper bound of the interval. If neither of the max fields are set, then
    /// the upper bound is positive infinity.
    ///
    /// This field must be not smaller than min.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    pub max: std::option::Option<crate::model::interval::Max>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Interval {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [min][crate::model::Interval::min].
    ///
    /// Note that all the setters affecting `min` are mutually
    /// exclusive.
    pub fn set_min<T: std::convert::Into<std::option::Option<crate::model::interval::Min>>>(
        mut self,
        v: T,
    ) -> Self {
        self.min = v.into();
        self
    }

    /// The value of [min][crate::model::Interval::min]
    /// if it holds a `Minimum`, `None` if the field is not set or
    /// holds a different branch.
    pub fn minimum(&self) -> std::option::Option<&f64> {
        #[allow(unreachable_patterns)]
        self.min.as_ref().and_then(|v| match v {
            crate::model::interval::Min::Minimum(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [min][crate::model::Interval::min]
    /// to hold a `Minimum`.
    ///
    /// Note that all the setters affecting `min` are
    /// mutually exclusive.
    pub fn set_minimum<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.min = std::option::Option::Some(crate::model::interval::Min::Minimum(v.into()));
        self
    }

    /// The value of [min][crate::model::Interval::min]
    /// if it holds a `ExclusiveMinimum`, `None` if the field is not set or
    /// holds a different branch.
    pub fn exclusive_minimum(&self) -> std::option::Option<&f64> {
        #[allow(unreachable_patterns)]
        self.min.as_ref().and_then(|v| match v {
            crate::model::interval::Min::ExclusiveMinimum(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [min][crate::model::Interval::min]
    /// to hold a `ExclusiveMinimum`.
    ///
    /// Note that all the setters affecting `min` are
    /// mutually exclusive.
    pub fn set_exclusive_minimum<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.min =
            std::option::Option::Some(crate::model::interval::Min::ExclusiveMinimum(v.into()));
        self
    }

    /// Sets the value of [max][crate::model::Interval::max].
    ///
    /// Note that all the setters affecting `max` are mutually
    /// exclusive.
    pub fn set_max<T: std::convert::Into<std::option::Option<crate::model::interval::Max>>>(
        mut self,
        v: T,
    ) -> Self {
        self.max = v.into();
        self
    }

    /// The value of [max][crate::model::Interval::max]
    /// if it holds a `Maximum`, `None` if the field is not set or
    /// holds a different branch.
    pub fn maximum(&self) -> std::option::Option<&f64> {
        #[allow(unreachable_patterns)]
        self.max.as_ref().and_then(|v| match v {
            crate::model::interval::Max::Maximum(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [max][crate::model::Interval::max]
    /// to hold a `Maximum`.
    ///
    /// Note that all the setters affecting `max` are
    /// mutually exclusive.
    pub fn set_maximum<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.max = std::option::Option::Some(crate::model::interval::Max::Maximum(v.into()));
        self
    }

    /// The value of [max][crate::model::Interval::max]
    /// if it holds a `ExclusiveMaximum`, `None` if the field is not set or
    /// holds a different branch.
    pub fn exclusive_maximum(&self) -> std::option::Option<&f64> {
        #[allow(unreachable_patterns)]
        self.max.as_ref().and_then(|v| match v {
            crate::model::interval::Max::ExclusiveMaximum(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [max][crate::model::Interval::max]
    /// to hold a `ExclusiveMaximum`.
    ///
    /// Note that all the setters affecting `max` are
    /// mutually exclusive.
    pub fn set_exclusive_maximum<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.max =
            std::option::Option::Some(crate::model::interval::Max::ExclusiveMaximum(v.into()));
        self
    }
}

impl wkt::message::Message for Interval {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Interval"
    }
}

/// Defines additional types related to [Interval].
pub mod interval {
    #[allow(unused_imports)]
    use super::*;

    /// The lower bound of the interval. If neither of the min fields are set, then
    /// the lower bound is negative infinity.
    ///
    /// This field must not be larger than max.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Min {
        /// Inclusive lower bound.
        Minimum(f64),
        /// Exclusive lower bound.
        ExclusiveMinimum(f64),
    }

    /// The upper bound of the interval. If neither of the max fields are set, then
    /// the upper bound is positive infinity.
    ///
    /// This field must be not smaller than min.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Max {
        /// Inclusive upper bound.
        Maximum(f64),
        /// Exclusive upper bound.
        ExclusiveMaximum(f64),
    }
}

/// The price information of a [Product][google.cloud.retail.v2.Product].
///
/// [google.cloud.retail.v2.Product]: crate::model::Product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PriceInfo {
    /// The 3-letter currency code defined in [ISO
    /// 4217](https://www.iso.org/iso-4217-currency-codes.html).
    ///
    /// If this field is an unrecognizable currency code, an INVALID_ARGUMENT
    /// error is returned.
    ///
    /// The [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
    /// [Product][google.cloud.retail.v2.Product]s with the same
    /// [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]
    /// must share the same
    /// [currency_code][google.cloud.retail.v2.PriceInfo.currency_code]. Otherwise,
    /// a FAILED_PRECONDITION error is returned.
    ///
    /// [google.cloud.retail.v2.PriceInfo.currency_code]: crate::model::PriceInfo::currency_code
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.Product.primary_product_id]: crate::model::Product::primary_product_id
    pub currency_code: std::string::String,

    /// Price of the product.
    ///
    /// Google Merchant Center property
    /// [price](https://support.google.com/merchants/answer/6324371). Schema.org
    /// property [Offer.price](https://schema.org/price).
    pub price: f32,

    /// Price of the product without any discount. If zero, by default set to be
    /// the [price][google.cloud.retail.v2.PriceInfo.price]. If set,
    /// [original_price][google.cloud.retail.v2.PriceInfo.original_price] should be
    /// greater than or equal to [price][google.cloud.retail.v2.PriceInfo.price],
    /// otherwise an INVALID_ARGUMENT error is thrown.
    ///
    /// [google.cloud.retail.v2.PriceInfo.original_price]: crate::model::PriceInfo::original_price
    /// [google.cloud.retail.v2.PriceInfo.price]: crate::model::PriceInfo::price
    pub original_price: f32,

    /// The costs associated with the sale of a particular product. Used for gross
    /// profit reporting.
    ///
    /// * Profit = [price][google.cloud.retail.v2.PriceInfo.price] -
    ///   [cost][google.cloud.retail.v2.PriceInfo.cost]
    ///
    /// Google Merchant Center property
    /// [cost_of_goods_sold](https://support.google.com/merchants/answer/9017895).
    ///
    /// [google.cloud.retail.v2.PriceInfo.cost]: crate::model::PriceInfo::cost
    /// [google.cloud.retail.v2.PriceInfo.price]: crate::model::PriceInfo::price
    pub cost: f32,

    /// The timestamp when the [price][google.cloud.retail.v2.PriceInfo.price]
    /// starts to be effective. This can be set as a future timestamp, and the
    /// [price][google.cloud.retail.v2.PriceInfo.price] is only used for search
    /// after
    /// [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time].
    /// If so, the
    /// [original_price][google.cloud.retail.v2.PriceInfo.original_price] must be
    /// set and [original_price][google.cloud.retail.v2.PriceInfo.original_price]
    /// is used before
    /// [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time].
    ///
    /// Do not set if [price][google.cloud.retail.v2.PriceInfo.price] is always
    /// effective because it will cause additional latency during search.
    ///
    /// [google.cloud.retail.v2.PriceInfo.original_price]: crate::model::PriceInfo::original_price
    /// [google.cloud.retail.v2.PriceInfo.price]: crate::model::PriceInfo::price
    /// [google.cloud.retail.v2.PriceInfo.price_effective_time]: crate::model::PriceInfo::price_effective_time
    pub price_effective_time: std::option::Option<wkt::Timestamp>,

    /// The timestamp when the [price][google.cloud.retail.v2.PriceInfo.price]
    /// stops to be effective. The [price][google.cloud.retail.v2.PriceInfo.price]
    /// is used for search before
    /// [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. If
    /// this field is set, the
    /// [original_price][google.cloud.retail.v2.PriceInfo.original_price] must be
    /// set and [original_price][google.cloud.retail.v2.PriceInfo.original_price]
    /// is used after
    /// [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time].
    ///
    /// Do not set if [price][google.cloud.retail.v2.PriceInfo.price] is always
    /// effective because it will cause additional latency during search.
    ///
    /// [google.cloud.retail.v2.PriceInfo.original_price]: crate::model::PriceInfo::original_price
    /// [google.cloud.retail.v2.PriceInfo.price]: crate::model::PriceInfo::price
    /// [google.cloud.retail.v2.PriceInfo.price_expire_time]: crate::model::PriceInfo::price_expire_time
    pub price_expire_time: std::option::Option<wkt::Timestamp>,

    /// Output only. The price range of all the child
    /// [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
    /// [Product][google.cloud.retail.v2.Product]s grouped together on the
    /// [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product]. Only populated for
    /// [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product]s.
    ///
    /// Note: This field is OUTPUT_ONLY for
    /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct].
    /// Do not set this field in API requests.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.ProductService.GetProduct]: crate::client::ProductService::get_product
    pub price_range: std::option::Option<crate::model::price_info::PriceRange>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PriceInfo {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [currency_code][crate::model::PriceInfo::currency_code].
    pub fn set_currency_code<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.currency_code = v.into();
        self
    }

    /// Sets the value of [price][crate::model::PriceInfo::price].
    pub fn set_price<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.price = v.into();
        self
    }

    /// Sets the value of [original_price][crate::model::PriceInfo::original_price].
    pub fn set_original_price<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.original_price = v.into();
        self
    }

    /// Sets the value of [cost][crate::model::PriceInfo::cost].
    pub fn set_cost<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.cost = v.into();
        self
    }

    /// Sets the value of [price_effective_time][crate::model::PriceInfo::price_effective_time].
    pub fn set_price_effective_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.price_effective_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [price_effective_time][crate::model::PriceInfo::price_effective_time].
    pub fn set_or_clear_price_effective_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.price_effective_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [price_expire_time][crate::model::PriceInfo::price_expire_time].
    pub fn set_price_expire_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.price_expire_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [price_expire_time][crate::model::PriceInfo::price_expire_time].
    pub fn set_or_clear_price_expire_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.price_expire_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [price_range][crate::model::PriceInfo::price_range].
    pub fn set_price_range<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::price_info::PriceRange>,
    {
        self.price_range = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [price_range][crate::model::PriceInfo::price_range].
    pub fn set_or_clear_price_range<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::price_info::PriceRange>,
    {
        self.price_range = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for PriceInfo {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PriceInfo"
    }
}

/// Defines additional types related to [PriceInfo].
pub mod price_info {
    #[allow(unused_imports)]
    use super::*;

    /// The price range of all
    /// [variant][google.cloud.retail.v2.Product.Type.VARIANT]
    /// [Product][google.cloud.retail.v2.Product] having the same
    /// [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id].
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.Product.primary_product_id]: crate::model::Product::primary_product_id
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct PriceRange {
        /// The inclusive
        /// [Product.pricing_info.price][google.cloud.retail.v2.PriceInfo.price]
        /// interval of all [variant][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product] having the same
        /// [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id].
        ///
        /// [google.cloud.retail.v2.PriceInfo.price]: crate::model::PriceInfo::price
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        /// [google.cloud.retail.v2.Product.primary_product_id]: crate::model::Product::primary_product_id
        pub price: std::option::Option<crate::model::Interval>,

        /// The inclusive
        /// [Product.pricing_info.original_price][google.cloud.retail.v2.PriceInfo.original_price]
        /// internal of all [variant][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product] having the same
        /// [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id].
        ///
        /// [google.cloud.retail.v2.PriceInfo.original_price]: crate::model::PriceInfo::original_price
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        /// [google.cloud.retail.v2.Product.primary_product_id]: crate::model::Product::primary_product_id
        pub original_price: std::option::Option<crate::model::Interval>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl PriceRange {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [price][crate::model::price_info::PriceRange::price].
        pub fn set_price<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Interval>,
        {
            self.price = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [price][crate::model::price_info::PriceRange::price].
        pub fn set_or_clear_price<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Interval>,
        {
            self.price = v.map(|x| x.into());
            self
        }

        /// Sets the value of [original_price][crate::model::price_info::PriceRange::original_price].
        pub fn set_original_price<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Interval>,
        {
            self.original_price = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [original_price][crate::model::price_info::PriceRange::original_price].
        pub fn set_or_clear_original_price<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Interval>,
        {
            self.original_price = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for PriceRange {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.PriceInfo.PriceRange"
        }
    }
}

/// The rating of a [Product][google.cloud.retail.v2.Product].
///
/// [google.cloud.retail.v2.Product]: crate::model::Product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Rating {
    /// The total number of ratings. This value is independent of the value of
    /// [rating_histogram][google.cloud.retail.v2.Rating.rating_histogram].
    ///
    /// This value must be nonnegative. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    ///
    /// [google.cloud.retail.v2.Rating.rating_histogram]: crate::model::Rating::rating_histogram
    pub rating_count: i32,

    /// The average rating of the [Product][google.cloud.retail.v2.Product].
    ///
    /// The rating is scaled at 1-5. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub average_rating: f32,

    /// List of rating counts per rating value (index = rating - 1). The list is
    /// empty if there is no rating. If the list is non-empty, its size is
    /// always 5. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// For example, [41, 14, 13, 47, 303]. It means that the
    /// [Product][google.cloud.retail.v2.Product] got 41 ratings with 1 star, 14
    /// ratings with 2 star, and so on.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub rating_histogram: std::vec::Vec<i32>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Rating {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [rating_count][crate::model::Rating::rating_count].
    pub fn set_rating_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.rating_count = v.into();
        self
    }

    /// Sets the value of [average_rating][crate::model::Rating::average_rating].
    pub fn set_average_rating<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.average_rating = v.into();
        self
    }

    /// Sets the value of [rating_histogram][crate::model::Rating::rating_histogram].
    pub fn set_rating_histogram<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.rating_histogram = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for Rating {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Rating"
    }
}

/// Information of an end user.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UserInfo {
    /// Highly recommended for logged-in users. Unique identifier for logged-in
    /// user, such as a user name. Don't set for anonymous users.
    ///
    /// Always use a hashed value for this ID.
    ///
    /// Don't set the field to the same fixed ID for different users. This mixes
    /// the event history of those users together, which results in degraded
    /// model quality.
    ///
    /// The field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    pub user_id: std::string::String,

    /// The end user's IP address. This field is used to extract location
    /// information for personalization.
    ///
    /// This field must be either an IPv4 address (e.g. "104.133.9.80") or an IPv6
    /// address (e.g. "2001:0db8:85a3:0000:0000:8a2e:0370:7334"). Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// This should not be set when:
    ///
    /// * setting
    ///   [SearchRequest.user_info][google.cloud.retail.v2.SearchRequest.user_info].
    /// * using the JavaScript tag in
    ///   [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent]
    ///   or if
    ///   [direct_user_request][google.cloud.retail.v2.UserInfo.direct_user_request]
    ///   is set.
    ///
    /// [google.cloud.retail.v2.SearchRequest.user_info]: crate::model::SearchRequest::user_info
    /// [google.cloud.retail.v2.UserEventService.CollectUserEvent]: crate::client::UserEventService::collect_user_event
    /// [google.cloud.retail.v2.UserInfo.direct_user_request]: crate::model::UserInfo::direct_user_request
    pub ip_address: std::string::String,

    /// User agent as included in the HTTP header.
    /// The field must be a UTF-8 encoded string with a length limit of 1,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// This should not be set when using the client side event reporting with
    /// GTM or JavaScript tag in
    /// [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent]
    /// or if
    /// [direct_user_request][google.cloud.retail.v2.UserInfo.direct_user_request]
    /// is set.
    ///
    /// [google.cloud.retail.v2.UserEventService.CollectUserEvent]: crate::client::UserEventService::collect_user_event
    /// [google.cloud.retail.v2.UserInfo.direct_user_request]: crate::model::UserInfo::direct_user_request
    pub user_agent: std::string::String,

    /// True if the request is made directly from the end user, in which case the
    /// [ip_address][google.cloud.retail.v2.UserInfo.ip_address] and
    /// [user_agent][google.cloud.retail.v2.UserInfo.user_agent] can be populated
    /// from the HTTP request. This flag should be set only if the API request is
    /// made directly from the end user such as a mobile app (and not if a gateway
    /// or a server is processing and pushing the user events).
    ///
    /// This should not be set when using the JavaScript tag in
    /// [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent].
    ///
    /// [google.cloud.retail.v2.UserEventService.CollectUserEvent]: crate::client::UserEventService::collect_user_event
    /// [google.cloud.retail.v2.UserInfo.ip_address]: crate::model::UserInfo::ip_address
    /// [google.cloud.retail.v2.UserInfo.user_agent]: crate::model::UserInfo::user_agent
    pub direct_user_request: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UserInfo {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [user_id][crate::model::UserInfo::user_id].
    pub fn set_user_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.user_id = v.into();
        self
    }

    /// Sets the value of [ip_address][crate::model::UserInfo::ip_address].
    pub fn set_ip_address<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.ip_address = v.into();
        self
    }

    /// Sets the value of [user_agent][crate::model::UserInfo::user_agent].
    pub fn set_user_agent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.user_agent = v.into();
        self
    }

    /// Sets the value of [direct_user_request][crate::model::UserInfo::direct_user_request].
    pub fn set_direct_user_request<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.direct_user_request = v.into();
        self
    }
}

impl wkt::message::Message for UserInfo {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UserInfo"
    }
}

/// The inventory information at a place (e.g. a store) identified
/// by a place ID.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct LocalInventory {
    /// Optional. The place ID for the current set of inventory information.
    pub place_id: std::string::String,

    /// Optional. Product price and cost information.
    ///
    /// Google Merchant Center property
    /// [price](https://support.google.com/merchants/answer/6324371).
    pub price_info: std::option::Option<crate::model::PriceInfo>,

    /// Optional. Additional local inventory attributes, for example, store name,
    /// promotion tags, etc.
    ///
    /// This field needs to pass all below criteria, otherwise an INVALID_ARGUMENT
    /// error is returned:
    ///
    /// * At most 30 attributes are allowed.
    /// * The key must be a UTF-8 encoded string with a length limit of 32
    ///   characters.
    /// * The key must match the pattern: `[a-zA-Z0-9][a-zA-Z0-9_]*`. For example,
    ///   key0LikeThis or KEY_1_LIKE_THIS.
    /// * The attribute values must be of the same type (text or number).
    /// * Only 1 value is allowed for each attribute.
    /// * For text values, the length limit is 256 UTF-8 characters.
    /// * The attribute does not support search. The `searchable` field should be
    ///   unset or set to false.
    /// * The max summed total bytes of custom attribute keys and values per
    ///   product is 5MiB.
    pub attributes: std::collections::HashMap<std::string::String, crate::model::CustomAttribute>,

    /// Optional. Supported fulfillment types. Valid fulfillment type values
    /// include commonly used types (such as pickup in store and same day
    /// delivery), and custom types. Customers have to map custom types to their
    /// display names before rendering UI.
    ///
    /// Supported values:
    ///
    /// * "pickup-in-store"
    /// * "ship-to-store"
    /// * "same-day-delivery"
    /// * "next-day-delivery"
    /// * "custom-type-1"
    /// * "custom-type-2"
    /// * "custom-type-3"
    /// * "custom-type-4"
    /// * "custom-type-5"
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// All the elements must be distinct. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    pub fulfillment_types: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl LocalInventory {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [place_id][crate::model::LocalInventory::place_id].
    pub fn set_place_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.place_id = v.into();
        self
    }

    /// Sets the value of [price_info][crate::model::LocalInventory::price_info].
    pub fn set_price_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::PriceInfo>,
    {
        self.price_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [price_info][crate::model::LocalInventory::price_info].
    pub fn set_or_clear_price_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::PriceInfo>,
    {
        self.price_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [attributes][crate::model::LocalInventory::attributes].
    pub fn set_attributes<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::CustomAttribute>,
    {
        use std::iter::Iterator;
        self.attributes = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [fulfillment_types][crate::model::LocalInventory::fulfillment_types].
    pub fn set_fulfillment_types<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.fulfillment_types = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for LocalInventory {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.LocalInventory"
    }
}

/// Metadata for pinning to be returned in the response.
/// This is used for distinguishing between applied vs dropped pins.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PinControlMetadata {
    /// Map of all matched pins, keyed by pin position.
    pub all_matched_pins:
        std::collections::HashMap<i64, crate::model::pin_control_metadata::ProductPins>,

    /// Map of pins that were dropped due to overlap with other matching pins,
    /// keyed by pin position.
    pub dropped_pins:
        std::collections::HashMap<i64, crate::model::pin_control_metadata::ProductPins>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PinControlMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [all_matched_pins][crate::model::PinControlMetadata::all_matched_pins].
    pub fn set_all_matched_pins<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<i64>,
        V: std::convert::Into<crate::model::pin_control_metadata::ProductPins>,
    {
        use std::iter::Iterator;
        self.all_matched_pins = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [dropped_pins][crate::model::PinControlMetadata::dropped_pins].
    pub fn set_dropped_pins<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<i64>,
        V: std::convert::Into<crate::model::pin_control_metadata::ProductPins>,
    {
        use std::iter::Iterator;
        self.dropped_pins = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for PinControlMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PinControlMetadata"
    }
}

/// Defines additional types related to [PinControlMetadata].
pub mod pin_control_metadata {
    #[allow(unused_imports)]
    use super::*;

    /// List of product ids which have associated pins.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ProductPins {
        /// List of product ids which have associated pins.
        pub product_id: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ProductPins {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [product_id][crate::model::pin_control_metadata::ProductPins::product_id].
        pub fn set_product_id<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.product_id = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for ProductPins {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.PinControlMetadata.ProductPins"
        }
    }
}

/// A list of string values.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct StringList {
    /// String values.
    pub values: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl StringList {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [values][crate::model::StringList::values].
    pub fn set_values<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.values = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for StringList {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.StringList"
    }
}

/// A message with a list of double values.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DoubleList {
    /// The list of double values.
    pub values: std::vec::Vec<f64>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DoubleList {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [values][crate::model::DoubleList::values].
    pub fn set_values<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<f64>,
    {
        use std::iter::Iterator;
        self.values = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for DoubleList {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.DoubleList"
    }
}

/// Autocomplete parameters.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CompleteQueryRequest {
    /// Required. Catalog for which the completion is performed.
    ///
    /// Full resource name of catalog, such as
    /// `projects/*/locations/global/catalogs/default_catalog`.
    pub catalog: std::string::String,

    /// Required. The query used to generate suggestions.
    ///
    /// The maximum number of allowed characters is 255.
    pub query: std::string::String,

    /// Recommended field. A unique identifier for tracking visitors. For example,
    /// this could be implemented with an HTTP cookie, which should be able to
    /// uniquely identify a visitor on a single device. This unique identifier
    /// should not change if the visitor logs in or out of the website.
    ///
    /// The field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    pub visitor_id: std::string::String,

    /// Note that this field applies for `user-data` dataset only. For requests
    /// with `cloud-retail` dataset, setting this field has no effect.
    ///
    /// The language filters applied to the output suggestions. If set, it should
    /// contain the language of the query. If not set, suggestions are returned
    /// without considering language restrictions. This is the BCP-47 language
    /// code, such as "en-US" or "sr-Latn". For more information, see [Tags for
    /// Identifying Languages](https://tools.ietf.org/html/bcp47). The maximum
    /// number of language codes is 3.
    pub language_codes: std::vec::Vec<std::string::String>,

    /// The device type context for completion suggestions. We recommend that you
    /// leave this field empty.
    ///
    /// It can apply different suggestions on different device types, e.g.
    /// `DESKTOP`, `MOBILE`. If it is empty, the suggestions are across all device
    /// types.
    ///
    /// Supported formats:
    ///
    /// * `UNKNOWN_DEVICE_TYPE`
    ///
    /// * `DESKTOP`
    ///
    /// * `MOBILE`
    ///
    /// * A customized string starts with `OTHER_`, e.g. `OTHER_IPHONE`.
    ///
    pub device_type: std::string::String,

    /// Determines which dataset to use for fetching completion. "user-data" will
    /// use the dataset imported through
    /// [CompletionService.ImportCompletionData][google.cloud.retail.v2.CompletionService.ImportCompletionData].
    /// `cloud-retail` will use the dataset generated by Cloud Retail based on user
    /// events. If left empty, completions will be fetched from the `user-data`
    /// dataset.
    ///
    /// Current supported values:
    ///
    /// * user-data
    ///
    /// * cloud-retail:
    ///   This option requires enabling auto-learning function first. See
    ///   [guidelines](https://cloud.google.com/retail/docs/completion-overview#generated-completion-dataset).
    ///
    ///
    /// [google.cloud.retail.v2.CompletionService.ImportCompletionData]: crate::client::CompletionService::import_completion_data
    pub dataset: std::string::String,

    /// Completion max suggestions. If left unset or set to 0, then will fallback
    /// to the configured value
    /// [CompletionConfig.max_suggestions][google.cloud.retail.v2.CompletionConfig.max_suggestions].
    ///
    /// The maximum allowed max suggestions is 20. If it is set higher, it will be
    /// capped by 20.
    ///
    /// [google.cloud.retail.v2.CompletionConfig.max_suggestions]: crate::model::CompletionConfig::max_suggestions
    pub max_suggestions: i32,

    /// If true, attribute suggestions are enabled and provided in the response.
    ///
    /// This field is only available for the `cloud-retail` dataset.
    pub enable_attribute_suggestions: bool,

    /// The entity for customers who run multiple entities, domains, sites, or
    /// regions, for example, `Google US`, `Google Ads`, `Waymo`,
    /// `google.com`, `youtube.com`, etc.
    /// If this is set, it must be an exact match with
    /// [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] to get
    /// per-entity autocomplete results. This field will be applied to
    /// `completion_results` only. It has no effect on the `attribute_results`.
    /// Also, this entity should be limited to 256 characters, if too long, it will
    /// be truncated to 256 characters in both generation and serving time, and may
    /// lead to mis-match. To ensure it works, please set the entity with string
    /// within 256 characters.
    ///
    /// [google.cloud.retail.v2.UserEvent.entity]: crate::model::UserEvent::entity
    pub entity: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CompleteQueryRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::CompleteQueryRequest::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }

    /// Sets the value of [query][crate::model::CompleteQueryRequest::query].
    pub fn set_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.query = v.into();
        self
    }

    /// Sets the value of [visitor_id][crate::model::CompleteQueryRequest::visitor_id].
    pub fn set_visitor_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.visitor_id = v.into();
        self
    }

    /// Sets the value of [language_codes][crate::model::CompleteQueryRequest::language_codes].
    pub fn set_language_codes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.language_codes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [device_type][crate::model::CompleteQueryRequest::device_type].
    pub fn set_device_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.device_type = v.into();
        self
    }

    /// Sets the value of [dataset][crate::model::CompleteQueryRequest::dataset].
    pub fn set_dataset<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.dataset = v.into();
        self
    }

    /// Sets the value of [max_suggestions][crate::model::CompleteQueryRequest::max_suggestions].
    pub fn set_max_suggestions<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.max_suggestions = v.into();
        self
    }

    /// Sets the value of [enable_attribute_suggestions][crate::model::CompleteQueryRequest::enable_attribute_suggestions].
    pub fn set_enable_attribute_suggestions<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.enable_attribute_suggestions = v.into();
        self
    }

    /// Sets the value of [entity][crate::model::CompleteQueryRequest::entity].
    pub fn set_entity<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.entity = v.into();
        self
    }
}

impl wkt::message::Message for CompleteQueryRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CompleteQueryRequest"
    }
}

/// Response of the autocomplete query.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CompleteQueryResponse {
    /// Results of the matching suggestions. The result list is ordered and the
    /// first result is top suggestion.
    pub completion_results: std::vec::Vec<crate::model::complete_query_response::CompletionResult>,

    /// A unique complete token. This should be included in the
    /// [UserEvent.completion_detail][google.cloud.retail.v2.UserEvent.completion_detail]
    /// for search events resulting from this completion, which enables accurate
    /// attribution of complete model performance.
    ///
    /// [google.cloud.retail.v2.UserEvent.completion_detail]: crate::model::UserEvent::completion_detail
    pub attribution_token: std::string::String,

    /// Deprecated. Matched recent searches of this user. The maximum number of
    /// recent searches is 10. This field is a restricted feature. If you want to
    /// enable it, contact Retail Search support.
    ///
    /// This feature is only available when
    /// [CompleteQueryRequest.visitor_id][google.cloud.retail.v2.CompleteQueryRequest.visitor_id]
    /// field is set and [UserEvent][google.cloud.retail.v2.UserEvent] is imported.
    /// The recent searches satisfy the follow rules:
    ///
    /// * They are ordered from latest to oldest.
    ///
    /// * They are matched with
    ///   [CompleteQueryRequest.query][google.cloud.retail.v2.CompleteQueryRequest.query]
    ///   case insensitively.
    ///
    /// * They are transformed to lower case.
    ///
    /// * They are UTF-8 safe.
    ///
    ///
    /// Recent searches are deduplicated. More recent searches will be reserved
    /// when duplication happens.
    ///
    /// [google.cloud.retail.v2.CompleteQueryRequest.query]: crate::model::CompleteQueryRequest::query
    /// [google.cloud.retail.v2.CompleteQueryRequest.visitor_id]: crate::model::CompleteQueryRequest::visitor_id
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    #[deprecated]
    pub recent_search_results:
        std::vec::Vec<crate::model::complete_query_response::RecentSearchResult>,

    /// A map of matched attribute suggestions. This field is only available for
    /// `cloud-retail` dataset.
    ///
    /// Current supported keys:
    ///
    /// * `brands`
    ///
    /// * `categories`
    ///
    pub attribute_results: std::collections::HashMap<
        std::string::String,
        crate::model::complete_query_response::AttributeResult,
    >,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CompleteQueryResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [completion_results][crate::model::CompleteQueryResponse::completion_results].
    pub fn set_completion_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::complete_query_response::CompletionResult>,
    {
        use std::iter::Iterator;
        self.completion_results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [attribution_token][crate::model::CompleteQueryResponse::attribution_token].
    pub fn set_attribution_token<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attribution_token = v.into();
        self
    }

    /// Sets the value of [recent_search_results][crate::model::CompleteQueryResponse::recent_search_results].
    #[deprecated]
    pub fn set_recent_search_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::complete_query_response::RecentSearchResult>,
    {
        use std::iter::Iterator;
        self.recent_search_results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [attribute_results][crate::model::CompleteQueryResponse::attribute_results].
    pub fn set_attribute_results<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::complete_query_response::AttributeResult>,
    {
        use std::iter::Iterator;
        self.attribute_results = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for CompleteQueryResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CompleteQueryResponse"
    }
}

/// Defines additional types related to [CompleteQueryResponse].
pub mod complete_query_response {
    #[allow(unused_imports)]
    use super::*;

    /// Resource that represents completion results.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct CompletionResult {
        /// The suggestion for the query.
        pub suggestion: std::string::String,

        /// Custom attributes for the suggestion term.
        ///
        /// * For `user-data`, the attributes are additional custom attributes
        ///   ingested through BigQuery.
        ///
        /// * For `cloud-retail`, the attributes are product attributes generated
        ///   by Cloud Retail. It requires
        ///   [UserEvent.product_details][google.cloud.retail.v2.UserEvent.product_details]
        ///   is imported properly.
        ///
        ///
        /// [google.cloud.retail.v2.UserEvent.product_details]: crate::model::UserEvent::product_details
        pub attributes:
            std::collections::HashMap<std::string::String, crate::model::CustomAttribute>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl CompletionResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [suggestion][crate::model::complete_query_response::CompletionResult::suggestion].
        pub fn set_suggestion<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.suggestion = v.into();
            self
        }

        /// Sets the value of [attributes][crate::model::complete_query_response::CompletionResult::attributes].
        pub fn set_attributes<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<crate::model::CustomAttribute>,
        {
            use std::iter::Iterator;
            self.attributes = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }
    }

    impl wkt::message::Message for CompletionResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.CompleteQueryResponse.CompletionResult"
        }
    }

    /// Deprecated: Recent search of this user.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    #[deprecated]
    pub struct RecentSearchResult {
        /// The recent search query.
        pub recent_search: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl RecentSearchResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [recent_search][crate::model::complete_query_response::RecentSearchResult::recent_search].
        pub fn set_recent_search<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.recent_search = v.into();
            self
        }
    }

    impl wkt::message::Message for RecentSearchResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.CompleteQueryResponse.RecentSearchResult"
        }
    }

    /// Resource that represents attribute results.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct AttributeResult {
        /// The list of suggestions for the attribute.
        pub suggestions: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl AttributeResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [suggestions][crate::model::complete_query_response::AttributeResult::suggestions].
        pub fn set_suggestions<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.suggestions = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for AttributeResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.CompleteQueryResponse.AttributeResult"
        }
    }
}

/// Configures dynamic metadata that can be linked to a
/// [ServingConfig][google.cloud.retail.v2.ServingConfig] and affect search or
/// recommendation results at serving time.
///
/// [google.cloud.retail.v2.ServingConfig]: crate::model::ServingConfig
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Control {
    /// Immutable. Fully qualified name
    /// `projects/*/locations/global/catalogs/*/controls/*`
    pub name: std::string::String,

    /// Required. The human readable control display name. Used in Retail UI.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is thrown.
    pub display_name: std::string::String,

    /// Output only. List of [serving config][google.cloud.retail.v2.ServingConfig]
    /// ids that are associated with this control in the same
    /// [Catalog][google.cloud.retail.v2.Catalog].
    ///
    /// Note the association is managed via the
    /// [ServingConfig][google.cloud.retail.v2.ServingConfig], this is an output
    /// only denormalized view.
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    /// [google.cloud.retail.v2.ServingConfig]: crate::model::ServingConfig
    pub associated_serving_config_ids: std::vec::Vec<std::string::String>,

    /// Required. Immutable. The solution types that the control is used for.
    /// Currently we support setting only one type of solution at creation time.
    ///
    /// Only `SOLUTION_TYPE_SEARCH` value is supported at the moment.
    /// If no solution type is provided at creation time, will default to
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub solution_types: std::vec::Vec<crate::model::SolutionType>,

    /// Specifies the use case for the control.
    /// Affects what condition fields can be set.
    /// Only settable by search controls.
    /// Will default to
    /// [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH]
    /// if not specified. Currently only allow one search_solution_use_case per
    /// control.
    ///
    /// [google.cloud.retail.v2.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH]: crate::model::SearchSolutionUseCase::Search
    pub search_solution_use_case: std::vec::Vec<crate::model::SearchSolutionUseCase>,

    /// The behavior/type of the control
    ///
    /// A behavior/type must be specified on creation. Type cannot be changed once
    /// specified (e.g. A Rule control will always be a Rule control.). An
    /// INVALID_ARGUMENT will be returned if either condition is violated.
    pub control: std::option::Option<crate::model::control::Control>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Control {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::Control::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [display_name][crate::model::Control::display_name].
    pub fn set_display_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.display_name = v.into();
        self
    }

    /// Sets the value of [associated_serving_config_ids][crate::model::Control::associated_serving_config_ids].
    pub fn set_associated_serving_config_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.associated_serving_config_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [solution_types][crate::model::Control::solution_types].
    pub fn set_solution_types<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::SolutionType>,
    {
        use std::iter::Iterator;
        self.solution_types = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [search_solution_use_case][crate::model::Control::search_solution_use_case].
    pub fn set_search_solution_use_case<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::SearchSolutionUseCase>,
    {
        use std::iter::Iterator;
        self.search_solution_use_case = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [control][crate::model::Control::control].
    ///
    /// Note that all the setters affecting `control` are mutually
    /// exclusive.
    pub fn set_control<
        T: std::convert::Into<std::option::Option<crate::model::control::Control>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.control = v.into();
        self
    }

    /// The value of [control][crate::model::Control::control]
    /// if it holds a `Rule`, `None` if the field is not set or
    /// holds a different branch.
    pub fn rule(&self) -> std::option::Option<&std::boxed::Box<crate::model::Rule>> {
        #[allow(unreachable_patterns)]
        self.control.as_ref().and_then(|v| match v {
            crate::model::control::Control::Rule(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [control][crate::model::Control::control]
    /// to hold a `Rule`.
    ///
    /// Note that all the setters affecting `control` are
    /// mutually exclusive.
    pub fn set_rule<T: std::convert::Into<std::boxed::Box<crate::model::Rule>>>(
        mut self,
        v: T,
    ) -> Self {
        self.control = std::option::Option::Some(crate::model::control::Control::Rule(v.into()));
        self
    }
}

impl wkt::message::Message for Control {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Control"
    }
}

/// Defines additional types related to [Control].
pub mod control {
    #[allow(unused_imports)]
    use super::*;

    /// The behavior/type of the control
    ///
    /// A behavior/type must be specified on creation. Type cannot be changed once
    /// specified (e.g. A Rule control will always be a Rule control.). An
    /// INVALID_ARGUMENT will be returned if either condition is violated.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Control {
        /// A rule control - a condition-action pair.
        /// Enacts a set action when the condition is triggered.
        /// For example: Boost "gShoe" when query full matches "Running Shoes".
        Rule(std::boxed::Box<crate::model::Rule>),
    }
}

/// Request for CreateControl method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CreateControlRequest {
    /// Required. Full resource name of parent catalog. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`
    pub parent: std::string::String,

    /// Required. The Control to create.
    pub control: std::option::Option<crate::model::Control>,

    /// Required. The ID to use for the Control, which will become the final
    /// component of the Control's resource name.
    ///
    /// This value should be 4-63 characters, and valid characters
    /// are /[a-z][0-9]-_/.
    pub control_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CreateControlRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::CreateControlRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [control][crate::model::CreateControlRequest::control].
    pub fn set_control<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Control>,
    {
        self.control = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [control][crate::model::CreateControlRequest::control].
    pub fn set_or_clear_control<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Control>,
    {
        self.control = v.map(|x| x.into());
        self
    }

    /// Sets the value of [control_id][crate::model::CreateControlRequest::control_id].
    pub fn set_control_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.control_id = v.into();
        self
    }
}

impl wkt::message::Message for CreateControlRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CreateControlRequest"
    }
}

/// Request for UpdateControl method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateControlRequest {
    /// Required. The Control to update.
    pub control: std::option::Option<crate::model::Control>,

    /// Indicates which fields in the provided
    /// [Control][google.cloud.retail.v2.Control] to update. The following are NOT
    /// supported:
    ///
    /// * [Control.name][google.cloud.retail.v2.Control.name]
    ///
    /// If not set or empty, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.Control]: crate::model::Control
    /// [google.cloud.retail.v2.Control.name]: crate::model::Control::name
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateControlRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [control][crate::model::UpdateControlRequest::control].
    pub fn set_control<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Control>,
    {
        self.control = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [control][crate::model::UpdateControlRequest::control].
    pub fn set_or_clear_control<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Control>,
    {
        self.control = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateControlRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateControlRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateControlRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateControlRequest"
    }
}

/// Request for DeleteControl method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DeleteControlRequest {
    /// Required. The resource name of the Control to delete. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DeleteControlRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::DeleteControlRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for DeleteControlRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.DeleteControlRequest"
    }
}

/// Request for GetControl method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetControlRequest {
    /// Required. The resource name of the Control to get. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetControlRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetControlRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for GetControlRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetControlRequest"
    }
}

/// Request for ListControls method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListControlsRequest {
    /// Required. The catalog resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`
    pub parent: std::string::String,

    /// Optional. Maximum number of results to return. If unspecified, defaults
    /// to 50. Max allowed value is 1000.
    pub page_size: i32,

    /// Optional. A page token, received from a previous `ListControls` call.
    /// Provide this to retrieve the subsequent page.
    pub page_token: std::string::String,

    /// Optional. A filter to apply on the list results. Supported features:
    ///
    /// * List all the products under the parent branch if
    ///   [filter][google.cloud.retail.v2.ListControlsRequest.filter] is unset.
    /// * List controls that are used in a single ServingConfig:
    ///   'serving_config = "boosted_home_page_cvr"'
    ///
    /// [google.cloud.retail.v2.ListControlsRequest.filter]: crate::model::ListControlsRequest::filter
    pub filter: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListControlsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListControlsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListControlsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListControlsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::ListControlsRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }
}

impl wkt::message::Message for ListControlsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListControlsRequest"
    }
}

/// Response for ListControls method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListControlsResponse {
    /// All the Controls for a given catalog.
    pub controls: std::vec::Vec<crate::model::Control>,

    /// Pagination token, if not returned indicates the last page.
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListControlsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [controls][crate::model::ListControlsResponse::controls].
    pub fn set_controls<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Control>,
    {
        use std::iter::Iterator;
        self.controls = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListControlsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListControlsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListControlsResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for ListControlsResponse {
    type PageItem = crate::model::Control;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.controls
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// Request message for
/// [ConversationalSearchService.ConversationalSearch][google.cloud.retail.v2.ConversationalSearchService.ConversationalSearch]
/// method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ConversationalSearchRequest {
    /// Required. The resource name of the search engine placement, such as
    /// `projects/*/locations/global/catalogs/default_catalog/placements/default_search`
    /// or
    /// `projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`
    /// This field is used to identify the serving config name and the set
    /// of models that will be used to make the search.
    pub placement: std::string::String,

    /// Required. The branch resource name, such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/0`.
    ///
    /// Use "default_branch" as the branch ID or leave this field empty, to search
    /// products under the default branch.
    pub branch: std::string::String,

    /// Optional. Raw search query to be searched for.
    ///
    /// If this field is empty, the request is considered a category browsing
    /// request.
    pub query: std::string::String,

    /// Optional. The categories associated with a category page. Must be set for
    /// category navigation queries to achieve good search quality. The format
    /// should be the same as
    /// [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories];
    ///
    /// To represent full path of category, use '>' sign to separate different
    /// hierarchies. If '>' is part of the category name, replace it with
    /// other character(s).
    ///
    /// Category pages include special pages such as sales or promotions. For
    /// instance, a special sale page may have the category hierarchy:
    /// "pageCategories" : ["Sales > 2017 Black Friday Deals"].
    ///
    /// [google.cloud.retail.v2.UserEvent.page_categories]: crate::model::UserEvent::page_categories
    pub page_categories: std::vec::Vec<std::string::String>,

    /// Optional. This field specifies the conversation id, which maintains the
    /// state of the conversation between client side and server side. Use the
    /// value from the previous
    /// [ConversationalSearchResponse.conversation_id][google.cloud.retail.v2.ConversationalSearchResponse.conversation_id].
    /// For the initial request, this should be empty.
    ///
    /// [google.cloud.retail.v2.ConversationalSearchResponse.conversation_id]: crate::model::ConversationalSearchResponse::conversation_id
    pub conversation_id: std::string::String,

    /// Optional. Search parameters.
    pub search_params:
        std::option::Option<crate::model::conversational_search_request::SearchParams>,

    /// Required. A unique identifier for tracking visitors. For example, this
    /// could be implemented with an HTTP cookie, which should be able to uniquely
    /// identify a visitor on a single device. This unique identifier should not
    /// change if the visitor logs in or out of the website.
    ///
    /// This should be the same identifier as
    /// [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id].
    ///
    /// The field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.UserEvent.visitor_id]: crate::model::UserEvent::visitor_id
    pub visitor_id: std::string::String,

    /// Optional. User information.
    pub user_info: std::option::Option<crate::model::UserInfo>,

    /// Optional. This field specifies all conversational filtering related
    /// parameters.
    pub conversational_filtering_spec: std::option::Option<
        crate::model::conversational_search_request::ConversationalFilteringSpec,
    >,

    /// Optional. The user labels applied to a resource must meet the following
    /// requirements:
    ///
    /// * Each resource can have multiple labels, up to a maximum of 64.
    /// * Each label must be a key-value pair.
    /// * Keys have a minimum length of 1 character and a maximum length of 63
    ///   characters and cannot be empty. Values can be empty and have a maximum
    ///   length of 63 characters.
    /// * Keys and values can contain only lowercase letters, numeric characters,
    ///   underscores, and dashes. All characters must use UTF-8 encoding, and
    ///   international characters are allowed.
    /// * The key portion of a label must be unique. However, you can use the same
    ///   key with multiple resources.
    /// * Keys must start with a lowercase letter or international character.
    ///
    /// See [Google Cloud
    /// Document](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements)
    /// for more details.
    pub user_labels: std::collections::HashMap<std::string::String, std::string::String>,

    /// Optional. The safety settings to be applied to the generated content.
    pub safety_settings: std::vec::Vec<crate::model::SafetySetting>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ConversationalSearchRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [placement][crate::model::ConversationalSearchRequest::placement].
    pub fn set_placement<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.placement = v.into();
        self
    }

    /// Sets the value of [branch][crate::model::ConversationalSearchRequest::branch].
    pub fn set_branch<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.branch = v.into();
        self
    }

    /// Sets the value of [query][crate::model::ConversationalSearchRequest::query].
    pub fn set_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.query = v.into();
        self
    }

    /// Sets the value of [page_categories][crate::model::ConversationalSearchRequest::page_categories].
    pub fn set_page_categories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.page_categories = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [conversation_id][crate::model::ConversationalSearchRequest::conversation_id].
    pub fn set_conversation_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.conversation_id = v.into();
        self
    }

    /// Sets the value of [search_params][crate::model::ConversationalSearchRequest::search_params].
    pub fn set_search_params<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::conversational_search_request::SearchParams>,
    {
        self.search_params = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [search_params][crate::model::ConversationalSearchRequest::search_params].
    pub fn set_or_clear_search_params<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::conversational_search_request::SearchParams>,
    {
        self.search_params = v.map(|x| x.into());
        self
    }

    /// Sets the value of [visitor_id][crate::model::ConversationalSearchRequest::visitor_id].
    pub fn set_visitor_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.visitor_id = v.into();
        self
    }

    /// Sets the value of [user_info][crate::model::ConversationalSearchRequest::user_info].
    pub fn set_user_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserInfo>,
    {
        self.user_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [user_info][crate::model::ConversationalSearchRequest::user_info].
    pub fn set_or_clear_user_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserInfo>,
    {
        self.user_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [conversational_filtering_spec][crate::model::ConversationalSearchRequest::conversational_filtering_spec].
    pub fn set_conversational_filtering_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<
                crate::model::conversational_search_request::ConversationalFilteringSpec,
            >,
    {
        self.conversational_filtering_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [conversational_filtering_spec][crate::model::ConversationalSearchRequest::conversational_filtering_spec].
    pub fn set_or_clear_conversational_filtering_spec<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<
                crate::model::conversational_search_request::ConversationalFilteringSpec,
            >,
    {
        self.conversational_filtering_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [user_labels][crate::model::ConversationalSearchRequest::user_labels].
    pub fn set_user_labels<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.user_labels = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [safety_settings][crate::model::ConversationalSearchRequest::safety_settings].
    pub fn set_safety_settings<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::SafetySetting>,
    {
        use std::iter::Iterator;
        self.safety_settings = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ConversationalSearchRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest"
    }
}

/// Defines additional types related to [ConversationalSearchRequest].
pub mod conversational_search_request {
    #[allow(unused_imports)]
    use super::*;

    /// Search parameters.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct SearchParams {
        /// Optional. The filter string to restrict search results.
        ///
        /// The syntax of the filter string is the same as
        /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter].
        ///
        /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
        pub filter: std::string::String,

        /// Optional. The canonical filter string to restrict search results.
        ///
        /// The syntax of the canonical filter string is the same as
        /// [SearchRequest.canonical_filter][google.cloud.retail.v2.SearchRequest.canonical_filter].
        ///
        /// [google.cloud.retail.v2.SearchRequest.canonical_filter]: crate::model::SearchRequest::canonical_filter
        pub canonical_filter: std::string::String,

        /// Optional. The sort string to specify the sorting of search results.
        ///
        /// The syntax of the sort string is the same as
        /// [SearchRequest.sort][].
        pub sort_by: std::string::String,

        /// Optional. The boost spec to specify the boosting of search results.
        ///
        /// The syntax of the boost spec is the same as
        /// [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec].
        ///
        /// [google.cloud.retail.v2.SearchRequest.boost_spec]: crate::model::SearchRequest::boost_spec
        pub boost_spec: std::option::Option<crate::model::search_request::BoostSpec>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl SearchParams {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [filter][crate::model::conversational_search_request::SearchParams::filter].
        pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.filter = v.into();
            self
        }

        /// Sets the value of [canonical_filter][crate::model::conversational_search_request::SearchParams::canonical_filter].
        pub fn set_canonical_filter<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.canonical_filter = v.into();
            self
        }

        /// Sets the value of [sort_by][crate::model::conversational_search_request::SearchParams::sort_by].
        pub fn set_sort_by<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.sort_by = v.into();
            self
        }

        /// Sets the value of [boost_spec][crate::model::conversational_search_request::SearchParams::boost_spec].
        pub fn set_boost_spec<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::search_request::BoostSpec>,
        {
            self.boost_spec = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [boost_spec][crate::model::conversational_search_request::SearchParams::boost_spec].
        pub fn set_or_clear_boost_spec<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::search_request::BoostSpec>,
        {
            self.boost_spec = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for SearchParams {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.SearchParams"
        }
    }

    /// This field specifies the current user answer during the conversational
    /// filtering search. This can be either user selected from suggested answers
    /// or user input plain text.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct UserAnswer {
        /// This field specifies the type of user answer.
        pub r#type:
            std::option::Option<crate::model::conversational_search_request::user_answer::Type>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl UserAnswer {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [r#type][crate::model::conversational_search_request::UserAnswer::type].
        ///
        /// Note that all the setters affecting `r#type` are mutually
        /// exclusive.
        pub fn set_type<
            T: std::convert::Into<
                    std::option::Option<
                        crate::model::conversational_search_request::user_answer::Type,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.r#type = v.into();
            self
        }

        /// The value of [r#type][crate::model::conversational_search_request::UserAnswer::r#type]
        /// if it holds a `TextAnswer`, `None` if the field is not set or
        /// holds a different branch.
        pub fn text_answer(&self) -> std::option::Option<&std::string::String> {
            #[allow(unreachable_patterns)]
            self.r#type.as_ref().and_then(|v| match v {
                crate::model::conversational_search_request::user_answer::Type::TextAnswer(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [r#type][crate::model::conversational_search_request::UserAnswer::r#type]
        /// to hold a `TextAnswer`.
        ///
        /// Note that all the setters affecting `r#type` are
        /// mutually exclusive.
        pub fn set_text_answer<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.r#type = std::option::Option::Some(
                crate::model::conversational_search_request::user_answer::Type::TextAnswer(
                    v.into(),
                ),
            );
            self
        }

        /// The value of [r#type][crate::model::conversational_search_request::UserAnswer::r#type]
        /// if it holds a `SelectedAnswer`, `None` if the field is not set or
        /// holds a different branch.
        pub fn selected_answer(
            &self,
        ) -> std::option::Option<
            &std::boxed::Box<
                crate::model::conversational_search_request::user_answer::SelectedAnswer,
            >,
        > {
            #[allow(unreachable_patterns)]
            self.r#type.as_ref().and_then(|v| match v {
                crate::model::conversational_search_request::user_answer::Type::SelectedAnswer(
                    v,
                ) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [r#type][crate::model::conversational_search_request::UserAnswer::r#type]
        /// to hold a `SelectedAnswer`.
        ///
        /// Note that all the setters affecting `r#type` are
        /// mutually exclusive.
        pub fn set_selected_answer<
            T: std::convert::Into<
                    std::boxed::Box<
                        crate::model::conversational_search_request::user_answer::SelectedAnswer,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.r#type = std::option::Option::Some(
                crate::model::conversational_search_request::user_answer::Type::SelectedAnswer(
                    v.into(),
                ),
            );
            self
        }
    }

    impl wkt::message::Message for UserAnswer {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.UserAnswer"
        }
    }

    /// Defines additional types related to [UserAnswer].
    pub mod user_answer {
        #[allow(unused_imports)]
        use super::*;

        /// This field specifies the selected answers during the conversational
        /// search.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct SelectedAnswer {
            /// Optional. This field specifies the selected answer which is a attribute
            /// key-value.
            pub product_attribute_value: std::option::Option<crate::model::ProductAttributeValue>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl SelectedAnswer {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [product_attribute_value][crate::model::conversational_search_request::user_answer::SelectedAnswer::product_attribute_value].
            pub fn set_product_attribute_value<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [product_attribute_value][crate::model::conversational_search_request::user_answer::SelectedAnswer::product_attribute_value].
            pub fn set_or_clear_product_attribute_value<T>(
                mut self,
                v: std::option::Option<T>,
            ) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for SelectedAnswer {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.UserAnswer.SelectedAnswer"
            }
        }

        /// This field specifies the type of user answer.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Type {
            /// This field specifies the incremental input text from the user during
            /// the conversational search.
            TextAnswer(std::string::String),
            /// Optional. This field specifies the selected answer during the
            /// conversational search. This should be a subset of
            /// [ConversationalSearchResponse.followup_question.suggested_answers][].
            SelectedAnswer(
                std::boxed::Box<
                    crate::model::conversational_search_request::user_answer::SelectedAnswer,
                >,
            ),
        }
    }

    /// This field specifies all conversational filtering related parameters
    /// addition to conversational retail search.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ConversationalFilteringSpec {
        /// Optional. This field is deprecated. Please use
        /// [ConversationalFilteringSpec.conversational_filtering_mode][google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.conversational_filtering_mode]
        /// instead.
        ///
        /// [google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.conversational_filtering_mode]: crate::model::conversational_search_request::ConversationalFilteringSpec::conversational_filtering_mode
        #[deprecated]
        pub enable_conversational_filtering: bool,

        /// Optional. This field specifies the current user answer during the
        /// conversational filtering search. It can be either user selected from
        /// suggested answers or user input plain text.
        pub user_answer:
            std::option::Option<crate::model::conversational_search_request::UserAnswer>,

        /// Optional. Mode to control Conversational Filtering.
        /// Defaults to
        /// [Mode.DISABLED][google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.Mode.DISABLED]
        /// if it's unset.
        ///
        /// [google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.Mode.DISABLED]: crate::model::conversational_search_request::conversational_filtering_spec::Mode::Disabled
        pub conversational_filtering_mode:
            crate::model::conversational_search_request::conversational_filtering_spec::Mode,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ConversationalFilteringSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [enable_conversational_filtering][crate::model::conversational_search_request::ConversationalFilteringSpec::enable_conversational_filtering].
        #[deprecated]
        pub fn set_enable_conversational_filtering<T: std::convert::Into<bool>>(
            mut self,
            v: T,
        ) -> Self {
            self.enable_conversational_filtering = v.into();
            self
        }

        /// Sets the value of [user_answer][crate::model::conversational_search_request::ConversationalFilteringSpec::user_answer].
        pub fn set_user_answer<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::conversational_search_request::UserAnswer>,
        {
            self.user_answer = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [user_answer][crate::model::conversational_search_request::ConversationalFilteringSpec::user_answer].
        pub fn set_or_clear_user_answer<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::conversational_search_request::UserAnswer>,
        {
            self.user_answer = v.map(|x| x.into());
            self
        }

        /// Sets the value of [conversational_filtering_mode][crate::model::conversational_search_request::ConversationalFilteringSpec::conversational_filtering_mode].
        pub fn set_conversational_filtering_mode<T: std::convert::Into<crate::model::conversational_search_request::conversational_filtering_spec::Mode>>(mut self, v: T) -> Self{
            self.conversational_filtering_mode = v.into();
            self
        }
    }

    impl wkt::message::Message for ConversationalFilteringSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec"
        }
    }

    /// Defines additional types related to [ConversationalFilteringSpec].
    pub mod conversational_filtering_spec {
        #[allow(unused_imports)]
        use super::*;

        /// Enum to control Conversational Filtering mode.
        /// A single conversation session including multiple turns supports modes for
        /// Conversational Search OR Conversational Filtering without
        /// Conversational Search, but not both.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Mode {
            /// Default value.
            Unspecified,
            /// Disables Conversational Filtering when using Conversational Search.
            Disabled,
            /// Enables Conversational Filtering when using Conversational Search.
            Enabled,
            /// Enables Conversational Filtering without Conversational Search.
            ConversationalFilterOnly,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Mode::value] or
            /// [Mode::name].
            UnknownValue(mode::UnknownValue),
        }

        #[doc(hidden)]
        pub mod mode {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Mode {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::Disabled => std::option::Option::Some(1),
                    Self::Enabled => std::option::Option::Some(2),
                    Self::ConversationalFilterOnly => std::option::Option::Some(3),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("MODE_UNSPECIFIED"),
                    Self::Disabled => std::option::Option::Some("DISABLED"),
                    Self::Enabled => std::option::Option::Some("ENABLED"),
                    Self::ConversationalFilterOnly => {
                        std::option::Option::Some("CONVERSATIONAL_FILTER_ONLY")
                    }
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Mode {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Mode {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Mode {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::Disabled,
                    2 => Self::Enabled,
                    3 => Self::ConversationalFilterOnly,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Mode {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "MODE_UNSPECIFIED" => Self::Unspecified,
                    "DISABLED" => Self::Disabled,
                    "ENABLED" => Self::Enabled,
                    "CONVERSATIONAL_FILTER_ONLY" => Self::ConversationalFilterOnly,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Mode {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::Disabled => serializer.serialize_i32(1),
                    Self::Enabled => serializer.serialize_i32(2),
                    Self::ConversationalFilterOnly => serializer.serialize_i32(3),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Mode {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Mode>::new(
                    ".google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.Mode"))
            }
        }
    }
}

/// Response message for
/// [ConversationalSearchService.ConversationalSearch][google.cloud.retail.v2.ConversationalSearchService.ConversationalSearch]
/// method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ConversationalSearchResponse {
    /// The types Retail classifies the search query as.
    ///
    /// Supported values are:
    ///
    /// - "ORDER_SUPPORT"
    /// - "SIMPLE_PRODUCT_SEARCH"
    /// - "INTENT_REFINEMENT"
    /// - "PRODUCT_DETAILS"
    /// - "PRODUCT_COMPARISON"
    /// - "DEALS_AND_COUPONS"
    /// - "STORE_RELEVANT"
    /// - "BLOCKLISTED"
    /// - "BEST_PRODUCT"
    /// - "RETAIL_SUPPORT"
    /// - "DISABLED"
    pub user_query_types: std::vec::Vec<std::string::String>,

    /// The conversational answer-based text response generated by the Server.
    pub conversational_text_response: std::string::String,

    /// The conversational followup question generated for Intent refinement.
    pub followup_question:
        std::option::Option<crate::model::conversational_search_response::FollowupQuestion>,

    /// Conversation UUID. This field will be stored in client side storage to
    /// maintain the conversation session with server and will be used for next
    /// search request's
    /// [ConversationalSearchRequest.conversation_id][google.cloud.retail.v2.ConversationalSearchRequest.conversation_id]
    /// to restore conversation state in server.
    ///
    /// [google.cloud.retail.v2.ConversationalSearchRequest.conversation_id]: crate::model::ConversationalSearchRequest::conversation_id
    pub conversation_id: std::string::String,

    /// The proposed refined search queries. They can be used to fetch the relevant
    /// search results. When using CONVERSATIONAL_FILTER_ONLY mode, the
    /// refined_query from search response will be populated here.
    pub refined_search: std::vec::Vec<crate::model::conversational_search_response::RefinedSearch>,

    /// This field specifies all related information that is needed on client
    /// side for UI rendering of conversational filtering search.
    pub conversational_filtering_result: std::option::Option<
        crate::model::conversational_search_response::ConversationalFilteringResult,
    >,

    /// Output only. The state of the response generation.
    pub state: crate::model::conversational_search_response::State,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ConversationalSearchResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [user_query_types][crate::model::ConversationalSearchResponse::user_query_types].
    pub fn set_user_query_types<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.user_query_types = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [conversational_text_response][crate::model::ConversationalSearchResponse::conversational_text_response].
    pub fn set_conversational_text_response<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.conversational_text_response = v.into();
        self
    }

    /// Sets the value of [followup_question][crate::model::ConversationalSearchResponse::followup_question].
    pub fn set_followup_question<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::conversational_search_response::FollowupQuestion>,
    {
        self.followup_question = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [followup_question][crate::model::ConversationalSearchResponse::followup_question].
    pub fn set_or_clear_followup_question<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::conversational_search_response::FollowupQuestion>,
    {
        self.followup_question = v.map(|x| x.into());
        self
    }

    /// Sets the value of [conversation_id][crate::model::ConversationalSearchResponse::conversation_id].
    pub fn set_conversation_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.conversation_id = v.into();
        self
    }

    /// Sets the value of [refined_search][crate::model::ConversationalSearchResponse::refined_search].
    pub fn set_refined_search<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::conversational_search_response::RefinedSearch>,
    {
        use std::iter::Iterator;
        self.refined_search = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [conversational_filtering_result][crate::model::ConversationalSearchResponse::conversational_filtering_result].
    pub fn set_conversational_filtering_result<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<
                crate::model::conversational_search_response::ConversationalFilteringResult,
            >,
    {
        self.conversational_filtering_result = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [conversational_filtering_result][crate::model::ConversationalSearchResponse::conversational_filtering_result].
    pub fn set_or_clear_conversational_filtering_result<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<
                crate::model::conversational_search_response::ConversationalFilteringResult,
            >,
    {
        self.conversational_filtering_result = v.map(|x| x.into());
        self
    }

    /// Sets the value of [state][crate::model::ConversationalSearchResponse::state].
    pub fn set_state<T: std::convert::Into<crate::model::conversational_search_response::State>>(
        mut self,
        v: T,
    ) -> Self {
        self.state = v.into();
        self
    }
}

impl wkt::message::Message for ConversationalSearchResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchResponse"
    }
}

/// Defines additional types related to [ConversationalSearchResponse].
pub mod conversational_search_response {
    #[allow(unused_imports)]
    use super::*;

    /// The conversational followup question generated for Intent refinement.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FollowupQuestion {
        /// The conversational followup question generated for Intent refinement.
        pub followup_question: std::string::String,

        /// The answer options provided to client for the follow-up question.
        pub suggested_answers: std::vec::Vec<
            crate::model::conversational_search_response::followup_question::SuggestedAnswer,
        >,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FollowupQuestion {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [followup_question][crate::model::conversational_search_response::FollowupQuestion::followup_question].
        pub fn set_followup_question<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.followup_question = v.into();
            self
        }

        /// Sets the value of [suggested_answers][crate::model::conversational_search_response::FollowupQuestion::suggested_answers].
        pub fn set_suggested_answers<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::conversational_search_response::followup_question::SuggestedAnswer>
        {
            use std::iter::Iterator;
            self.suggested_answers = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for FollowupQuestion {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchResponse.FollowupQuestion"
        }
    }

    /// Defines additional types related to [FollowupQuestion].
    pub mod followup_question {
        #[allow(unused_imports)]
        use super::*;

        /// Suggested answers to the follow-up question.
        /// If it's numerical attribute, only ProductAttributeInterval will be set.
        /// If it's textual attribute, only productAttributeValue will be set.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct SuggestedAnswer {
            /// Product attribute value, including an attribute key and an
            /// attribute value. Other types can be added here in the future.
            pub product_attribute_value: std::option::Option<crate::model::ProductAttributeValue>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl SuggestedAnswer {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [product_attribute_value][crate::model::conversational_search_response::followup_question::SuggestedAnswer::product_attribute_value].
            pub fn set_product_attribute_value<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [product_attribute_value][crate::model::conversational_search_response::followup_question::SuggestedAnswer::product_attribute_value].
            pub fn set_or_clear_product_attribute_value<T>(
                mut self,
                v: std::option::Option<T>,
            ) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for SuggestedAnswer {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchResponse.FollowupQuestion.SuggestedAnswer"
            }
        }
    }

    /// The proposed refined search for intent-refinement/bundled shopping
    /// conversation. When using CONVERSATIONAL_FILTER_ONLY mode, the
    /// refined_query from search response will be populated here.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct RefinedSearch {
        /// The query to be used for search.
        pub query: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl RefinedSearch {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [query][crate::model::conversational_search_response::RefinedSearch::query].
        pub fn set_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.query = v.into();
            self
        }
    }

    impl wkt::message::Message for RefinedSearch {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchResponse.RefinedSearch"
        }
    }

    /// This field specifies all related information that is needed on client
    /// side for UI rendering of conversational filtering search.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ConversationalFilteringResult {

        /// The conversational filtering question.
        pub followup_question: std::option::Option<crate::model::conversational_search_response::FollowupQuestion>,

        /// This is the incremental additional filters implied from the current
        /// user answer. User should add the suggested addition filters to the
        /// previous [ConversationalSearchRequest.search_params.filter][] and
        /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter],  and
        /// use the merged filter in the follow up requests.
        ///
        /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
        pub additional_filter: std::option::Option<crate::model::conversational_search_response::conversational_filtering_result::AdditionalFilter>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ConversationalFilteringResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [followup_question][crate::model::conversational_search_response::ConversationalFilteringResult::followup_question].
        pub fn set_followup_question<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::conversational_search_response::FollowupQuestion>,
        {
            self.followup_question = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [followup_question][crate::model::conversational_search_response::ConversationalFilteringResult::followup_question].
        pub fn set_or_clear_followup_question<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::conversational_search_response::FollowupQuestion>,
        {
            self.followup_question = v.map(|x| x.into());
            self
        }

        /// Sets the value of [additional_filter][crate::model::conversational_search_response::ConversationalFilteringResult::additional_filter].
        pub fn set_additional_filter<T>(mut self, v: T) -> Self
        where T: std::convert::Into<crate::model::conversational_search_response::conversational_filtering_result::AdditionalFilter>
        {
            self.additional_filter = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [additional_filter][crate::model::conversational_search_response::ConversationalFilteringResult::additional_filter].
        pub fn set_or_clear_additional_filter<T>(mut self, v: std::option::Option<T>) -> Self
        where T: std::convert::Into<crate::model::conversational_search_response::conversational_filtering_result::AdditionalFilter>
        {
            self.additional_filter = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for ConversationalFilteringResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchResponse.ConversationalFilteringResult"
        }
    }

    /// Defines additional types related to [ConversationalFilteringResult].
    pub mod conversational_filtering_result {
        #[allow(unused_imports)]
        use super::*;

        /// Additional filter that client side need to apply.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct AdditionalFilter {
            /// Product attribute value, including an attribute key and an
            /// attribute value. Other types can be added here in the future.
            pub product_attribute_value: std::option::Option<crate::model::ProductAttributeValue>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl AdditionalFilter {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [product_attribute_value][crate::model::conversational_search_response::conversational_filtering_result::AdditionalFilter::product_attribute_value].
            pub fn set_product_attribute_value<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [product_attribute_value][crate::model::conversational_search_response::conversational_filtering_result::AdditionalFilter::product_attribute_value].
            pub fn set_or_clear_product_attribute_value<T>(
                mut self,
                v: std::option::Option<T>,
            ) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for AdditionalFilter {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchResponse.ConversationalFilteringResult.AdditionalFilter"
            }
        }
    }

    /// The state of the response generation.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum State {
        /// Unknown.
        Unspecified,
        /// Response generation is being streamed.
        Streaming,
        /// Response generation has succeeded.
        Succeeded,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [State::value] or
        /// [State::name].
        UnknownValue(state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl State {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Streaming => std::option::Option::Some(1),
                Self::Succeeded => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("STATE_UNSPECIFIED"),
                Self::Streaming => std::option::Option::Some("STREAMING"),
                Self::Succeeded => std::option::Option::Some("SUCCEEDED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for State {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for State {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for State {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Streaming,
                2 => Self::Succeeded,
                _ => Self::UnknownValue(state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for State {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "STATE_UNSPECIFIED" => Self::Unspecified,
                "STREAMING" => Self::Streaming,
                "SUCCEEDED" => Self::Succeeded,
                _ => Self::UnknownValue(state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for State {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Streaming => serializer.serialize_i32(1),
                Self::Succeeded => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for State {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<State>::new(
                ".google.cloud.retail.v2.ConversationalSearchResponse.State",
            ))
        }
    }
}

/// The output configuration setting.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct OutputConfig {
    /// The configuration of destination for holding output data.
    pub destination: std::option::Option<crate::model::output_config::Destination>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl OutputConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [destination][crate::model::OutputConfig::destination].
    ///
    /// Note that all the setters affecting `destination` are mutually
    /// exclusive.
    pub fn set_destination<
        T: std::convert::Into<std::option::Option<crate::model::output_config::Destination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = v.into();
        self
    }

    /// The value of [destination][crate::model::OutputConfig::destination]
    /// if it holds a `GcsDestination`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_destination(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::output_config::GcsDestination>> {
        #[allow(unreachable_patterns)]
        self.destination.as_ref().and_then(|v| match v {
            crate::model::output_config::Destination::GcsDestination(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [destination][crate::model::OutputConfig::destination]
    /// to hold a `GcsDestination`.
    ///
    /// Note that all the setters affecting `destination` are
    /// mutually exclusive.
    pub fn set_gcs_destination<
        T: std::convert::Into<std::boxed::Box<crate::model::output_config::GcsDestination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = std::option::Option::Some(
            crate::model::output_config::Destination::GcsDestination(v.into()),
        );
        self
    }

    /// The value of [destination][crate::model::OutputConfig::destination]
    /// if it holds a `BigqueryDestination`, `None` if the field is not set or
    /// holds a different branch.
    pub fn bigquery_destination(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::output_config::BigQueryDestination>>
    {
        #[allow(unreachable_patterns)]
        self.destination.as_ref().and_then(|v| match v {
            crate::model::output_config::Destination::BigqueryDestination(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [destination][crate::model::OutputConfig::destination]
    /// to hold a `BigqueryDestination`.
    ///
    /// Note that all the setters affecting `destination` are
    /// mutually exclusive.
    pub fn set_bigquery_destination<
        T: std::convert::Into<std::boxed::Box<crate::model::output_config::BigQueryDestination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = std::option::Option::Some(
            crate::model::output_config::Destination::BigqueryDestination(v.into()),
        );
        self
    }
}

impl wkt::message::Message for OutputConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.OutputConfig"
    }
}

/// Defines additional types related to [OutputConfig].
pub mod output_config {
    #[allow(unused_imports)]
    use super::*;

    /// The Google Cloud Storage output destination configuration.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct GcsDestination {
        /// Required. The output uri prefix for saving output data to json files.
        /// Some mapping examples are as follows:
        /// output_uri_prefix         sample output(assuming the object is foo.json)
        /// ========================  =============================================
        /// gs://bucket/              gs://bucket/foo.json
        /// gs://bucket/folder/       gs://bucket/folder/foo.json
        /// gs://bucket/folder/item_  gs://bucket/folder/item_foo.json
        pub output_uri_prefix: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl GcsDestination {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [output_uri_prefix][crate::model::output_config::GcsDestination::output_uri_prefix].
        pub fn set_output_uri_prefix<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.output_uri_prefix = v.into();
            self
        }
    }

    impl wkt::message::Message for GcsDestination {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.OutputConfig.GcsDestination"
        }
    }

    /// The BigQuery output destination configuration.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct BigQueryDestination {
        /// Required. The ID of a BigQuery Dataset.
        pub dataset_id: std::string::String,

        /// Required. The prefix of exported BigQuery tables.
        pub table_id_prefix: std::string::String,

        /// Required. Describes the table type. The following values are supported:
        ///
        /// * `table`: A BigQuery native table.
        /// * `view`: A virtual table defined by a SQL query.
        pub table_type: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl BigQueryDestination {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [dataset_id][crate::model::output_config::BigQueryDestination::dataset_id].
        pub fn set_dataset_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.dataset_id = v.into();
            self
        }

        /// Sets the value of [table_id_prefix][crate::model::output_config::BigQueryDestination::table_id_prefix].
        pub fn set_table_id_prefix<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.table_id_prefix = v.into();
            self
        }

        /// Sets the value of [table_type][crate::model::output_config::BigQueryDestination::table_type].
        pub fn set_table_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.table_type = v.into();
            self
        }
    }

    impl wkt::message::Message for BigQueryDestination {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.OutputConfig.BigQueryDestination"
        }
    }

    /// The configuration of destination for holding output data.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Destination {
        /// The Google Cloud Storage location where the output is to be written to.
        GcsDestination(std::boxed::Box<crate::model::output_config::GcsDestination>),
        /// The BigQuery location where the output is to be written to.
        BigqueryDestination(std::boxed::Box<crate::model::output_config::BigQueryDestination>),
    }
}

/// Configuration of destination for Export related errors.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExportErrorsConfig {
    /// Required. Errors destination.
    pub destination: std::option::Option<crate::model::export_errors_config::Destination>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExportErrorsConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [destination][crate::model::ExportErrorsConfig::destination].
    ///
    /// Note that all the setters affecting `destination` are mutually
    /// exclusive.
    pub fn set_destination<
        T: std::convert::Into<std::option::Option<crate::model::export_errors_config::Destination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = v.into();
        self
    }

    /// The value of [destination][crate::model::ExportErrorsConfig::destination]
    /// if it holds a `GcsPrefix`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_prefix(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.destination.as_ref().and_then(|v| match v {
            crate::model::export_errors_config::Destination::GcsPrefix(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [destination][crate::model::ExportErrorsConfig::destination]
    /// to hold a `GcsPrefix`.
    ///
    /// Note that all the setters affecting `destination` are
    /// mutually exclusive.
    pub fn set_gcs_prefix<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.destination = std::option::Option::Some(
            crate::model::export_errors_config::Destination::GcsPrefix(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ExportErrorsConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ExportErrorsConfig"
    }
}

/// Defines additional types related to [ExportErrorsConfig].
pub mod export_errors_config {
    #[allow(unused_imports)]
    use super::*;

    /// Required. Errors destination.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Destination {
        /// Google Cloud Storage path for import errors. This must be an empty,
        /// existing Cloud Storage bucket. Export errors will be written to a file in
        /// this bucket, one per line, as a JSON-encoded
        /// `google.rpc.Status` message.
        GcsPrefix(std::string::String),
    }
}

/// Request message for the `ExportAnalyticsMetrics` method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExportAnalyticsMetricsRequest {
    /// Required. Full resource name of the parent catalog.
    /// Expected format: `projects/*/locations/*/catalogs/*`
    pub catalog: std::string::String,

    /// Required. The output location of the data.
    pub output_config: std::option::Option<crate::model::OutputConfig>,

    /// A filtering expression to specify restrictions on returned metrics.
    /// The expression is a sequence of terms. Each term applies a restriction to
    /// the returned metrics. Use this expression to restrict results to a
    /// specific time range.
    ///
    /// Currently we expect only one types of fields:
    ///
    /// * `timestamp`: This can be specified twice, once with a
    ///   less than operator and once with a greater than operator. The
    ///   `timestamp` restriction should result in one, contiguous, valid,
    ///   `timestamp` range.
    ///
    /// Some examples of valid filters expressions:
    ///
    /// * Example 1: `timestamp > "2012-04-23T18:25:43.511Z"
    ///   timestamp < "2012-04-23T18:30:43.511Z"`
    /// * Example 2: `timestamp > "2012-04-23T18:25:43.511Z"`
    pub filter: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExportAnalyticsMetricsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::ExportAnalyticsMetricsRequest::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }

    /// Sets the value of [output_config][crate::model::ExportAnalyticsMetricsRequest::output_config].
    pub fn set_output_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::OutputConfig>,
    {
        self.output_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [output_config][crate::model::ExportAnalyticsMetricsRequest::output_config].
    pub fn set_or_clear_output_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::OutputConfig>,
    {
        self.output_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [filter][crate::model::ExportAnalyticsMetricsRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }
}

impl wkt::message::Message for ExportAnalyticsMetricsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ExportAnalyticsMetricsRequest"
    }
}

/// Metadata related to the progress of the Export operation. This is
/// returned by the google.longrunning.Operation.metadata field.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExportMetadata {
    /// Operation create time.
    pub create_time: std::option::Option<wkt::Timestamp>,

    /// Operation last update time. If the operation is done, this is also the
    /// finish time.
    pub update_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExportMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [create_time][crate::model::ExportMetadata::create_time].
    pub fn set_create_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [create_time][crate::model::ExportMetadata::create_time].
    pub fn set_or_clear_create_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_time][crate::model::ExportMetadata::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::ExportMetadata::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ExportMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ExportMetadata"
    }
}

/// Response of the ExportAnalyticsMetricsRequest. If the long running
/// operation was successful, then this message is returned by the
/// google.longrunning.Operations.response field if the operation was successful.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExportAnalyticsMetricsResponse {
    /// A sample of errors encountered while processing the request.
    pub error_samples: std::vec::Vec<rpc::model::Status>,

    /// This field is never set.
    pub errors_config: std::option::Option<crate::model::ExportErrorsConfig>,

    /// Output result indicating where the data were exported to.
    pub output_result: std::option::Option<crate::model::OutputResult>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExportAnalyticsMetricsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [error_samples][crate::model::ExportAnalyticsMetricsResponse::error_samples].
    pub fn set_error_samples<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.error_samples = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [errors_config][crate::model::ExportAnalyticsMetricsResponse::errors_config].
    pub fn set_errors_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ExportErrorsConfig>,
    {
        self.errors_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [errors_config][crate::model::ExportAnalyticsMetricsResponse::errors_config].
    pub fn set_or_clear_errors_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ExportErrorsConfig>,
    {
        self.errors_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [output_result][crate::model::ExportAnalyticsMetricsResponse::output_result].
    pub fn set_output_result<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::OutputResult>,
    {
        self.output_result = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [output_result][crate::model::ExportAnalyticsMetricsResponse::output_result].
    pub fn set_or_clear_output_result<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::OutputResult>,
    {
        self.output_result = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ExportAnalyticsMetricsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ExportAnalyticsMetricsResponse"
    }
}

/// Output result that stores the information about where the exported data is
/// stored.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct OutputResult {
    /// The BigQuery location where the result is stored.
    pub bigquery_result: std::vec::Vec<crate::model::BigQueryOutputResult>,

    /// The Google Cloud Storage location where the result is stored.
    pub gcs_result: std::vec::Vec<crate::model::GcsOutputResult>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl OutputResult {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [bigquery_result][crate::model::OutputResult::bigquery_result].
    pub fn set_bigquery_result<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::BigQueryOutputResult>,
    {
        use std::iter::Iterator;
        self.bigquery_result = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [gcs_result][crate::model::OutputResult::gcs_result].
    pub fn set_gcs_result<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::GcsOutputResult>,
    {
        use std::iter::Iterator;
        self.gcs_result = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for OutputResult {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.OutputResult"
    }
}

/// A BigQuery output result.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BigQueryOutputResult {
    /// The ID of a BigQuery Dataset.
    pub dataset_id: std::string::String,

    /// The ID of a BigQuery Table.
    pub table_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BigQueryOutputResult {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [dataset_id][crate::model::BigQueryOutputResult::dataset_id].
    pub fn set_dataset_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.dataset_id = v.into();
        self
    }

    /// Sets the value of [table_id][crate::model::BigQueryOutputResult::table_id].
    pub fn set_table_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.table_id = v.into();
        self
    }
}

impl wkt::message::Message for BigQueryOutputResult {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.BigQueryOutputResult"
    }
}

/// A Gcs output result.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GcsOutputResult {
    /// The uri of Gcs output
    pub output_uri: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GcsOutputResult {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [output_uri][crate::model::GcsOutputResult::output_uri].
    pub fn set_output_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.output_uri = v.into();
        self
    }
}

impl wkt::message::Message for GcsOutputResult {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GcsOutputResult"
    }
}

/// Configuration for overall generative question feature state.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GenerativeQuestionsFeatureConfig {
    /// Required. Resource name of the affected catalog.
    /// Format: projects/{project}/locations/{location}/catalogs/{catalog}
    pub catalog: std::string::String,

    /// Optional. Determines whether questions will be used at serving time.
    /// Note: This feature cannot be enabled until initial data requirements are
    /// satisfied.
    pub feature_enabled: bool,

    /// Optional. Minimum number of products in the response to trigger follow-up
    /// questions. Value must be 0 or positive.
    pub minimum_products: i32,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GenerativeQuestionsFeatureConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::GenerativeQuestionsFeatureConfig::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }

    /// Sets the value of [feature_enabled][crate::model::GenerativeQuestionsFeatureConfig::feature_enabled].
    pub fn set_feature_enabled<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.feature_enabled = v.into();
        self
    }

    /// Sets the value of [minimum_products][crate::model::GenerativeQuestionsFeatureConfig::minimum_products].
    pub fn set_minimum_products<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.minimum_products = v.into();
        self
    }
}

impl wkt::message::Message for GenerativeQuestionsFeatureConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GenerativeQuestionsFeatureConfig"
    }
}

/// Configuration for a single generated question.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GenerativeQuestionConfig {
    /// Required. Resource name of the catalog.
    /// Format: projects/{project}/locations/{location}/catalogs/{catalog}
    pub catalog: std::string::String,

    /// Required. The facet to which the question is associated.
    pub facet: std::string::String,

    /// Output only. The LLM generated question.
    pub generated_question: std::string::String,

    /// Optional. The question that will be used at serving time.
    /// Question can have a max length of 300 bytes.
    /// When not populated, generated_question should be used.
    pub final_question: std::string::String,

    /// Output only. Values that can be used to answer the question.
    pub example_values: std::vec::Vec<std::string::String>,

    /// Output only. The ratio of how often a question was asked.
    pub frequency: f32,

    /// Optional. Whether the question is asked at serving time.
    pub allowed_in_conversation: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GenerativeQuestionConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::GenerativeQuestionConfig::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }

    /// Sets the value of [facet][crate::model::GenerativeQuestionConfig::facet].
    pub fn set_facet<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.facet = v.into();
        self
    }

    /// Sets the value of [generated_question][crate::model::GenerativeQuestionConfig::generated_question].
    pub fn set_generated_question<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.generated_question = v.into();
        self
    }

    /// Sets the value of [final_question][crate::model::GenerativeQuestionConfig::final_question].
    pub fn set_final_question<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.final_question = v.into();
        self
    }

    /// Sets the value of [example_values][crate::model::GenerativeQuestionConfig::example_values].
    pub fn set_example_values<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.example_values = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [frequency][crate::model::GenerativeQuestionConfig::frequency].
    pub fn set_frequency<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.frequency = v.into();
        self
    }

    /// Sets the value of [allowed_in_conversation][crate::model::GenerativeQuestionConfig::allowed_in_conversation].
    pub fn set_allowed_in_conversation<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allowed_in_conversation = v.into();
        self
    }
}

impl wkt::message::Message for GenerativeQuestionConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GenerativeQuestionConfig"
    }
}

/// Request for UpdateGenerativeQuestionsFeatureConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateGenerativeQuestionsFeatureConfigRequest {
    /// Required. The configuration managing the feature state.
    pub generative_questions_feature_config:
        std::option::Option<crate::model::GenerativeQuestionsFeatureConfig>,

    /// Optional. Indicates which fields in the provided
    /// [GenerativeQuestionsFeatureConfig][google.cloud.retail.v2.GenerativeQuestionsFeatureConfig]
    /// to update. If not set or empty, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.GenerativeQuestionsFeatureConfig]: crate::model::GenerativeQuestionsFeatureConfig
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateGenerativeQuestionsFeatureConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [generative_questions_feature_config][crate::model::UpdateGenerativeQuestionsFeatureConfigRequest::generative_questions_feature_config].
    pub fn set_generative_questions_feature_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::GenerativeQuestionsFeatureConfig>,
    {
        self.generative_questions_feature_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [generative_questions_feature_config][crate::model::UpdateGenerativeQuestionsFeatureConfigRequest::generative_questions_feature_config].
    pub fn set_or_clear_generative_questions_feature_config<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<crate::model::GenerativeQuestionsFeatureConfig>,
    {
        self.generative_questions_feature_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateGenerativeQuestionsFeatureConfigRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateGenerativeQuestionsFeatureConfigRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateGenerativeQuestionsFeatureConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateGenerativeQuestionsFeatureConfigRequest"
    }
}

/// Request for GetGenerativeQuestionsFeatureConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetGenerativeQuestionsFeatureConfigRequest {
    /// Required. Resource name of the parent catalog.
    /// Format: projects/{project}/locations/{location}/catalogs/{catalog}
    pub catalog: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetGenerativeQuestionsFeatureConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [catalog][crate::model::GetGenerativeQuestionsFeatureConfigRequest::catalog].
    pub fn set_catalog<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.catalog = v.into();
        self
    }
}

impl wkt::message::Message for GetGenerativeQuestionsFeatureConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetGenerativeQuestionsFeatureConfigRequest"
    }
}

/// Request for ListQuestions method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListGenerativeQuestionConfigsRequest {
    /// Required. Resource name of the parent catalog.
    /// Format: projects/{project}/locations/{location}/catalogs/{catalog}
    pub parent: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListGenerativeQuestionConfigsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListGenerativeQuestionConfigsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }
}

impl wkt::message::Message for ListGenerativeQuestionConfigsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListGenerativeQuestionConfigsRequest"
    }
}

/// Response for ListQuestions method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListGenerativeQuestionConfigsResponse {
    /// All the questions for a given catalog.
    pub generative_question_configs: std::vec::Vec<crate::model::GenerativeQuestionConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListGenerativeQuestionConfigsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [generative_question_configs][crate::model::ListGenerativeQuestionConfigsResponse::generative_question_configs].
    pub fn set_generative_question_configs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::GenerativeQuestionConfig>,
    {
        use std::iter::Iterator;
        self.generative_question_configs = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ListGenerativeQuestionConfigsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListGenerativeQuestionConfigsResponse"
    }
}

/// Request for UpdateGenerativeQuestionConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateGenerativeQuestionConfigRequest {
    /// Required. The question to update.
    pub generative_question_config: std::option::Option<crate::model::GenerativeQuestionConfig>,

    /// Optional. Indicates which fields in the provided
    /// [GenerativeQuestionConfig][google.cloud.retail.v2.GenerativeQuestionConfig]
    /// to update. The following are NOT supported:
    ///
    /// * [GenerativeQuestionConfig.frequency][google.cloud.retail.v2.GenerativeQuestionConfig.frequency]
    ///
    /// If not set or empty, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.GenerativeQuestionConfig]: crate::model::GenerativeQuestionConfig
    /// [google.cloud.retail.v2.GenerativeQuestionConfig.frequency]: crate::model::GenerativeQuestionConfig::frequency
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateGenerativeQuestionConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [generative_question_config][crate::model::UpdateGenerativeQuestionConfigRequest::generative_question_config].
    pub fn set_generative_question_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::GenerativeQuestionConfig>,
    {
        self.generative_question_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [generative_question_config][crate::model::UpdateGenerativeQuestionConfigRequest::generative_question_config].
    pub fn set_or_clear_generative_question_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::GenerativeQuestionConfig>,
    {
        self.generative_question_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateGenerativeQuestionConfigRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateGenerativeQuestionConfigRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateGenerativeQuestionConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateGenerativeQuestionConfigRequest"
    }
}

/// Request for BatchUpdateGenerativeQuestionConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchUpdateGenerativeQuestionConfigsRequest {
    /// Optional. Resource name of the parent catalog.
    /// Format: projects/{project}/locations/{location}/catalogs/{catalog}
    pub parent: std::string::String,

    /// Required. The updates question configs.
    pub requests: std::vec::Vec<crate::model::UpdateGenerativeQuestionConfigRequest>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchUpdateGenerativeQuestionConfigsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::BatchUpdateGenerativeQuestionConfigsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [requests][crate::model::BatchUpdateGenerativeQuestionConfigsRequest::requests].
    pub fn set_requests<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::UpdateGenerativeQuestionConfigRequest>,
    {
        use std::iter::Iterator;
        self.requests = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for BatchUpdateGenerativeQuestionConfigsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.BatchUpdateGenerativeQuestionConfigsRequest"
    }
}

/// Aggregated response for UpdateGenerativeQuestionConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchUpdateGenerativeQuestionConfigsResponse {
    /// Optional. The updates question configs.
    pub generative_question_configs: std::vec::Vec<crate::model::GenerativeQuestionConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchUpdateGenerativeQuestionConfigsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [generative_question_configs][crate::model::BatchUpdateGenerativeQuestionConfigsResponse::generative_question_configs].
    pub fn set_generative_question_configs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::GenerativeQuestionConfig>,
    {
        use std::iter::Iterator;
        self.generative_question_configs = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for BatchUpdateGenerativeQuestionConfigsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.BatchUpdateGenerativeQuestionConfigsResponse"
    }
}

/// Google Cloud Storage location for input content.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GcsSource {
    /// Required. Google Cloud Storage URIs to input files. URI can be up to
    /// 2000 characters long. URIs can match the full object path (for example,
    /// `gs://bucket/directory/object.json`) or a pattern matching one or more
    /// files, such as `gs://bucket/directory/*.json`. A request can
    /// contain at most 100 files, and each file can be up to 2 GB. See
    /// [Importing product
    /// information](https://cloud.google.com/retail/recommendations-ai/docs/upload-catalog)
    /// for the expected file format and setup instructions.
    pub input_uris: std::vec::Vec<std::string::String>,

    /// The schema to use when parsing the data from the source.
    ///
    /// Supported values for product imports:
    ///
    /// * `product` (default): One JSON [Product][google.cloud.retail.v2.Product]
    ///   per line. Each product must
    ///   have a valid [Product.id][google.cloud.retail.v2.Product.id].
    /// * `product_merchant_center`: See [Importing catalog data from Merchant
    ///   Center](https://cloud.google.com/retail/recommendations-ai/docs/upload-catalog#mc).
    ///
    /// Supported values for user events imports:
    ///
    /// * `user_event` (default): One JSON
    ///   [UserEvent][google.cloud.retail.v2.UserEvent] per line.
    /// * `user_event_ga360`: Using
    ///   <https://support.google.com/analytics/answer/3437719>.
    ///
    /// Supported values for control imports:
    ///
    /// * `control` (default): One JSON [Control][google.cloud.retail.v2.Control]
    ///   per line.
    ///
    /// Supported values for catalog attribute imports:
    ///
    /// * `catalog_attribute` (default): One CSV
    ///   [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] per line.
    ///
    /// [google.cloud.retail.v2.CatalogAttribute]: crate::model::CatalogAttribute
    /// [google.cloud.retail.v2.Control]: crate::model::Control
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    pub data_schema: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GcsSource {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [input_uris][crate::model::GcsSource::input_uris].
    pub fn set_input_uris<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.input_uris = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [data_schema][crate::model::GcsSource::data_schema].
    pub fn set_data_schema<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.data_schema = v.into();
        self
    }
}

impl wkt::message::Message for GcsSource {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GcsSource"
    }
}

/// BigQuery source import data from.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BigQuerySource {
    /// The project ID (can be project # or ID) that the BigQuery source is in with
    /// a length limit of 128 characters. If not specified, inherits the project
    /// ID from the parent request.
    pub project_id: std::string::String,

    /// Required. The BigQuery data set to copy the data from with a length limit
    /// of 1,024 characters.
    pub dataset_id: std::string::String,

    /// Required. The BigQuery table to copy the data from with a length limit of
    /// 1,024 characters.
    pub table_id: std::string::String,

    /// Intermediate Cloud Storage directory used for the import with a length
    /// limit of 2,000 characters. Can be specified if one wants to have the
    /// BigQuery export to a specific Cloud Storage directory.
    pub gcs_staging_dir: std::string::String,

    /// The schema to use when parsing the data from the source.
    ///
    /// Supported values for product imports:
    ///
    /// * `product` (default): One JSON [Product][google.cloud.retail.v2.Product]
    ///   per line. Each product must
    ///   have a valid [Product.id][google.cloud.retail.v2.Product.id].
    /// * `product_merchant_center`: See [Importing catalog data from Merchant
    ///   Center](https://cloud.google.com/retail/recommendations-ai/docs/upload-catalog#mc).
    ///
    /// Supported values for user events imports:
    ///
    /// * `user_event` (default): One JSON
    ///   [UserEvent][google.cloud.retail.v2.UserEvent] per line.
    /// * `user_event_ga360`:
    ///   The schema is available here:
    ///   <https://support.google.com/analytics/answer/3437719>.
    /// * `user_event_ga4`:
    ///   The schema is available here:
    ///   <https://support.google.com/analytics/answer/7029846>.
    ///
    /// Supported values for autocomplete imports:
    ///
    /// * `suggestions` (default): One JSON completion suggestion per line.
    /// * `denylist`:  One JSON deny suggestion per line.
    /// * `allowlist`:  One JSON allow suggestion per line.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    pub data_schema: std::string::String,

    /// BigQuery table partition info. Leave this empty if the BigQuery table
    /// is not partitioned.
    pub partition: std::option::Option<crate::model::big_query_source::Partition>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BigQuerySource {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [project_id][crate::model::BigQuerySource::project_id].
    pub fn set_project_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.project_id = v.into();
        self
    }

    /// Sets the value of [dataset_id][crate::model::BigQuerySource::dataset_id].
    pub fn set_dataset_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.dataset_id = v.into();
        self
    }

    /// Sets the value of [table_id][crate::model::BigQuerySource::table_id].
    pub fn set_table_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.table_id = v.into();
        self
    }

    /// Sets the value of [gcs_staging_dir][crate::model::BigQuerySource::gcs_staging_dir].
    pub fn set_gcs_staging_dir<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.gcs_staging_dir = v.into();
        self
    }

    /// Sets the value of [data_schema][crate::model::BigQuerySource::data_schema].
    pub fn set_data_schema<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.data_schema = v.into();
        self
    }

    /// Sets the value of [partition][crate::model::BigQuerySource::partition].
    ///
    /// Note that all the setters affecting `partition` are mutually
    /// exclusive.
    pub fn set_partition<
        T: std::convert::Into<std::option::Option<crate::model::big_query_source::Partition>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.partition = v.into();
        self
    }

    /// The value of [partition][crate::model::BigQuerySource::partition]
    /// if it holds a `PartitionDate`, `None` if the field is not set or
    /// holds a different branch.
    pub fn partition_date(&self) -> std::option::Option<&std::boxed::Box<gtype::model::Date>> {
        #[allow(unreachable_patterns)]
        self.partition.as_ref().and_then(|v| match v {
            crate::model::big_query_source::Partition::PartitionDate(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [partition][crate::model::BigQuerySource::partition]
    /// to hold a `PartitionDate`.
    ///
    /// Note that all the setters affecting `partition` are
    /// mutually exclusive.
    pub fn set_partition_date<T: std::convert::Into<std::boxed::Box<gtype::model::Date>>>(
        mut self,
        v: T,
    ) -> Self {
        self.partition = std::option::Option::Some(
            crate::model::big_query_source::Partition::PartitionDate(v.into()),
        );
        self
    }
}

impl wkt::message::Message for BigQuerySource {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.BigQuerySource"
    }
}

/// Defines additional types related to [BigQuerySource].
pub mod big_query_source {
    #[allow(unused_imports)]
    use super::*;

    /// BigQuery table partition info. Leave this empty if the BigQuery table
    /// is not partitioned.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Partition {
        /// BigQuery time partitioned table's _PARTITIONDATE in YYYY-MM-DD format.
        PartitionDate(std::boxed::Box<gtype::model::Date>),
    }
}

/// The inline source for the input config for ImportProducts method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ProductInlineSource {
    /// Required. A list of products to update/create. Each product must have a
    /// valid [Product.id][google.cloud.retail.v2.Product.id]. Recommended max of
    /// 100 items.
    ///
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    pub products: std::vec::Vec<crate::model::Product>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ProductInlineSource {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [products][crate::model::ProductInlineSource::products].
    pub fn set_products<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Product>,
    {
        use std::iter::Iterator;
        self.products = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ProductInlineSource {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ProductInlineSource"
    }
}

/// The inline source for the input config for ImportUserEvents method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UserEventInlineSource {
    /// Required. A list of user events to import. Recommended max of 10k items.
    pub user_events: std::vec::Vec<crate::model::UserEvent>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UserEventInlineSource {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [user_events][crate::model::UserEventInlineSource::user_events].
    pub fn set_user_events<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::UserEvent>,
    {
        use std::iter::Iterator;
        self.user_events = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for UserEventInlineSource {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UserEventInlineSource"
    }
}

/// Configuration of destination for Import related errors.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportErrorsConfig {
    /// Required. Errors destination.
    pub destination: std::option::Option<crate::model::import_errors_config::Destination>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportErrorsConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [destination][crate::model::ImportErrorsConfig::destination].
    ///
    /// Note that all the setters affecting `destination` are mutually
    /// exclusive.
    pub fn set_destination<
        T: std::convert::Into<std::option::Option<crate::model::import_errors_config::Destination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = v.into();
        self
    }

    /// The value of [destination][crate::model::ImportErrorsConfig::destination]
    /// if it holds a `GcsPrefix`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_prefix(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.destination.as_ref().and_then(|v| match v {
            crate::model::import_errors_config::Destination::GcsPrefix(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [destination][crate::model::ImportErrorsConfig::destination]
    /// to hold a `GcsPrefix`.
    ///
    /// Note that all the setters affecting `destination` are
    /// mutually exclusive.
    pub fn set_gcs_prefix<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.destination = std::option::Option::Some(
            crate::model::import_errors_config::Destination::GcsPrefix(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ImportErrorsConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportErrorsConfig"
    }
}

/// Defines additional types related to [ImportErrorsConfig].
pub mod import_errors_config {
    #[allow(unused_imports)]
    use super::*;

    /// Required. Errors destination.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Destination {
        /// Google Cloud Storage prefix for import errors. This must be an empty,
        /// existing Cloud Storage directory. Import errors are written to
        /// sharded files in this directory, one per line, as a JSON-encoded
        /// `google.rpc.Status` message.
        GcsPrefix(std::string::String),
    }
}

/// Request message for Import methods.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportProductsRequest {
    /// Required.
    /// `projects/1234/locations/global/catalogs/default_catalog/branches/default_branch`
    ///
    /// If no updateMask is specified, requires products.create permission.
    /// If updateMask is specified, requires products.update permission.
    pub parent: std::string::String,

    /// Deprecated. This field has no effect.
    #[deprecated]
    pub request_id: std::string::String,

    /// Required. The desired input location of the data.
    pub input_config: std::option::Option<crate::model::ProductInputConfig>,

    /// The desired location of errors incurred during the Import.
    pub errors_config: std::option::Option<crate::model::ImportErrorsConfig>,

    /// Indicates which fields in the provided imported `products` to update. If
    /// not set, all fields are updated. If provided, only the existing product
    /// fields are updated. Missing products will not be created.
    pub update_mask: std::option::Option<wkt::FieldMask>,

    /// The mode of reconciliation between existing products and the products to be
    /// imported. Defaults to
    /// [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2.ImportProductsRequest.ReconciliationMode.INCREMENTAL].
    ///
    /// [google.cloud.retail.v2.ImportProductsRequest.ReconciliationMode.INCREMENTAL]: crate::model::import_products_request::ReconciliationMode::Incremental
    pub reconciliation_mode: crate::model::import_products_request::ReconciliationMode,

    /// Full Pub/Sub topic name for receiving notification. If this field is set,
    /// when the import is finished, a notification is sent to
    /// specified Pub/Sub topic. The message data is JSON string of a
    /// [Operation][google.longrunning.Operation].
    ///
    /// Format of the Pub/Sub topic is `projects/{project}/topics/{topic}`. It has
    /// to be within the same project as
    /// [ImportProductsRequest.parent][google.cloud.retail.v2.ImportProductsRequest.parent].
    /// Make sure that both
    /// `cloud-retail-customer-data-access@system.gserviceaccount.com` and
    /// `service-<project number>@gcp-sa-retail.iam.gserviceaccount.com`
    /// have the `pubsub.topics.publish` IAM permission on the topic.
    ///
    /// Only supported when
    /// [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode]
    /// is set to `FULL`.
    ///
    /// [google.cloud.retail.v2.ImportProductsRequest.parent]: crate::model::ImportProductsRequest::parent
    /// [google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode]: crate::model::ImportProductsRequest::reconciliation_mode
    /// [google.longrunning.Operation]: longrunning::model::Operation
    pub notification_pubsub_topic: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportProductsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ImportProductsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [request_id][crate::model::ImportProductsRequest::request_id].
    #[deprecated]
    pub fn set_request_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.request_id = v.into();
        self
    }

    /// Sets the value of [input_config][crate::model::ImportProductsRequest::input_config].
    pub fn set_input_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ProductInputConfig>,
    {
        self.input_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [input_config][crate::model::ImportProductsRequest::input_config].
    pub fn set_or_clear_input_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ProductInputConfig>,
    {
        self.input_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [errors_config][crate::model::ImportProductsRequest::errors_config].
    pub fn set_errors_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [errors_config][crate::model::ImportProductsRequest::errors_config].
    pub fn set_or_clear_errors_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::ImportProductsRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::ImportProductsRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [reconciliation_mode][crate::model::ImportProductsRequest::reconciliation_mode].
    pub fn set_reconciliation_mode<
        T: std::convert::Into<crate::model::import_products_request::ReconciliationMode>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.reconciliation_mode = v.into();
        self
    }

    /// Sets the value of [notification_pubsub_topic][crate::model::ImportProductsRequest::notification_pubsub_topic].
    pub fn set_notification_pubsub_topic<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.notification_pubsub_topic = v.into();
        self
    }
}

impl wkt::message::Message for ImportProductsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportProductsRequest"
    }
}

/// Defines additional types related to [ImportProductsRequest].
pub mod import_products_request {
    #[allow(unused_imports)]
    use super::*;

    /// Indicates how imported products are reconciled with the existing products
    /// created or imported before.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ReconciliationMode {
        /// Defaults to INCREMENTAL.
        Unspecified,
        /// Inserts new products or updates existing products.
        Incremental,
        /// Calculates diff and replaces the entire product dataset. Existing
        /// products may be deleted if they are not present in the source location.
        Full,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [ReconciliationMode::value] or
        /// [ReconciliationMode::name].
        UnknownValue(reconciliation_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod reconciliation_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl ReconciliationMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Incremental => std::option::Option::Some(1),
                Self::Full => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("RECONCILIATION_MODE_UNSPECIFIED"),
                Self::Incremental => std::option::Option::Some("INCREMENTAL"),
                Self::Full => std::option::Option::Some("FULL"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for ReconciliationMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for ReconciliationMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for ReconciliationMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Incremental,
                2 => Self::Full,
                _ => Self::UnknownValue(reconciliation_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for ReconciliationMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "RECONCILIATION_MODE_UNSPECIFIED" => Self::Unspecified,
                "INCREMENTAL" => Self::Incremental,
                "FULL" => Self::Full,
                _ => Self::UnknownValue(reconciliation_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for ReconciliationMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Incremental => serializer.serialize_i32(1),
                Self::Full => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for ReconciliationMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<ReconciliationMode>::new(
                ".google.cloud.retail.v2.ImportProductsRequest.ReconciliationMode",
            ))
        }
    }
}

/// Request message for the ImportUserEvents request.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportUserEventsRequest {
    /// Required. `projects/1234/locations/global/catalogs/default_catalog`
    pub parent: std::string::String,

    /// Required. The desired input location of the data.
    pub input_config: std::option::Option<crate::model::UserEventInputConfig>,

    /// The desired location of errors incurred during the Import. Cannot be set
    /// for inline user event imports.
    pub errors_config: std::option::Option<crate::model::ImportErrorsConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportUserEventsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ImportUserEventsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [input_config][crate::model::ImportUserEventsRequest::input_config].
    pub fn set_input_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserEventInputConfig>,
    {
        self.input_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [input_config][crate::model::ImportUserEventsRequest::input_config].
    pub fn set_or_clear_input_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserEventInputConfig>,
    {
        self.input_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [errors_config][crate::model::ImportUserEventsRequest::errors_config].
    pub fn set_errors_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [errors_config][crate::model::ImportUserEventsRequest::errors_config].
    pub fn set_or_clear_errors_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ImportUserEventsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportUserEventsRequest"
    }
}

/// Request message for ImportCompletionData methods.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportCompletionDataRequest {
    /// Required. The catalog which the suggestions dataset belongs to.
    ///
    /// Format: `projects/1234/locations/global/catalogs/default_catalog`.
    pub parent: std::string::String,

    /// Required. The desired input location of the data.
    pub input_config: std::option::Option<crate::model::CompletionDataInputConfig>,

    /// Pub/Sub topic for receiving notification. If this field is set,
    /// when the import is finished, a notification is sent to
    /// specified Pub/Sub topic. The message data is JSON string of a
    /// [Operation][google.longrunning.Operation].
    /// Format of the Pub/Sub topic is `projects/{project}/topics/{topic}`.
    ///
    /// [google.longrunning.Operation]: longrunning::model::Operation
    pub notification_pubsub_topic: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportCompletionDataRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ImportCompletionDataRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [input_config][crate::model::ImportCompletionDataRequest::input_config].
    pub fn set_input_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.input_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [input_config][crate::model::ImportCompletionDataRequest::input_config].
    pub fn set_or_clear_input_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDataInputConfig>,
    {
        self.input_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [notification_pubsub_topic][crate::model::ImportCompletionDataRequest::notification_pubsub_topic].
    pub fn set_notification_pubsub_topic<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.notification_pubsub_topic = v.into();
        self
    }
}

impl wkt::message::Message for ImportCompletionDataRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportCompletionDataRequest"
    }
}

/// The input config source for products.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ProductInputConfig {
    /// Required. The source of the input.
    pub source: std::option::Option<crate::model::product_input_config::Source>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ProductInputConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [source][crate::model::ProductInputConfig::source].
    ///
    /// Note that all the setters affecting `source` are mutually
    /// exclusive.
    pub fn set_source<
        T: std::convert::Into<std::option::Option<crate::model::product_input_config::Source>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = v.into();
        self
    }

    /// The value of [source][crate::model::ProductInputConfig::source]
    /// if it holds a `ProductInlineSource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn product_inline_source(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::ProductInlineSource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::product_input_config::Source::ProductInlineSource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::ProductInputConfig::source]
    /// to hold a `ProductInlineSource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_product_inline_source<
        T: std::convert::Into<std::boxed::Box<crate::model::ProductInlineSource>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::product_input_config::Source::ProductInlineSource(v.into()),
        );
        self
    }

    /// The value of [source][crate::model::ProductInputConfig::source]
    /// if it holds a `GcsSource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_source(&self) -> std::option::Option<&std::boxed::Box<crate::model::GcsSource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::product_input_config::Source::GcsSource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::ProductInputConfig::source]
    /// to hold a `GcsSource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_gcs_source<T: std::convert::Into<std::boxed::Box<crate::model::GcsSource>>>(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::product_input_config::Source::GcsSource(v.into()),
        );
        self
    }

    /// The value of [source][crate::model::ProductInputConfig::source]
    /// if it holds a `BigQuerySource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn big_query_source(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::BigQuerySource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::product_input_config::Source::BigQuerySource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::ProductInputConfig::source]
    /// to hold a `BigQuerySource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_big_query_source<
        T: std::convert::Into<std::boxed::Box<crate::model::BigQuerySource>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::product_input_config::Source::BigQuerySource(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ProductInputConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ProductInputConfig"
    }
}

/// Defines additional types related to [ProductInputConfig].
pub mod product_input_config {
    #[allow(unused_imports)]
    use super::*;

    /// Required. The source of the input.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Source {
        /// The Inline source for the input content for products.
        ProductInlineSource(std::boxed::Box<crate::model::ProductInlineSource>),
        /// Google Cloud Storage location for the input content.
        GcsSource(std::boxed::Box<crate::model::GcsSource>),
        /// BigQuery input source.
        BigQuerySource(std::boxed::Box<crate::model::BigQuerySource>),
    }
}

/// The input config source for user events.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UserEventInputConfig {
    /// The source of the input.
    pub source: std::option::Option<crate::model::user_event_input_config::Source>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UserEventInputConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [source][crate::model::UserEventInputConfig::source].
    ///
    /// Note that all the setters affecting `source` are mutually
    /// exclusive.
    pub fn set_source<
        T: std::convert::Into<std::option::Option<crate::model::user_event_input_config::Source>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = v.into();
        self
    }

    /// The value of [source][crate::model::UserEventInputConfig::source]
    /// if it holds a `UserEventInlineSource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn user_event_inline_source(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::UserEventInlineSource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::user_event_input_config::Source::UserEventInlineSource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::UserEventInputConfig::source]
    /// to hold a `UserEventInlineSource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_user_event_inline_source<
        T: std::convert::Into<std::boxed::Box<crate::model::UserEventInlineSource>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::user_event_input_config::Source::UserEventInlineSource(v.into()),
        );
        self
    }

    /// The value of [source][crate::model::UserEventInputConfig::source]
    /// if it holds a `GcsSource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_source(&self) -> std::option::Option<&std::boxed::Box<crate::model::GcsSource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::user_event_input_config::Source::GcsSource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::UserEventInputConfig::source]
    /// to hold a `GcsSource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_gcs_source<T: std::convert::Into<std::boxed::Box<crate::model::GcsSource>>>(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::user_event_input_config::Source::GcsSource(v.into()),
        );
        self
    }

    /// The value of [source][crate::model::UserEventInputConfig::source]
    /// if it holds a `BigQuerySource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn big_query_source(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::BigQuerySource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::user_event_input_config::Source::BigQuerySource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::UserEventInputConfig::source]
    /// to hold a `BigQuerySource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_big_query_source<
        T: std::convert::Into<std::boxed::Box<crate::model::BigQuerySource>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::user_event_input_config::Source::BigQuerySource(v.into()),
        );
        self
    }
}

impl wkt::message::Message for UserEventInputConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UserEventInputConfig"
    }
}

/// Defines additional types related to [UserEventInputConfig].
pub mod user_event_input_config {
    #[allow(unused_imports)]
    use super::*;

    /// The source of the input.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Source {
        /// Required. The Inline source for the input content for UserEvents.
        UserEventInlineSource(std::boxed::Box<crate::model::UserEventInlineSource>),
        /// Required. Google Cloud Storage location for the input content.
        GcsSource(std::boxed::Box<crate::model::GcsSource>),
        /// Required. BigQuery input source.
        BigQuerySource(std::boxed::Box<crate::model::BigQuerySource>),
    }
}

/// The input config source for completion data.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CompletionDataInputConfig {
    /// The source of the input.
    ///
    /// Supported
    /// [BigQuerySource.data_schema][google.cloud.retail.v2.BigQuerySource.data_schema]
    /// values for suggestions imports:
    ///
    /// * `suggestions` (default): One JSON completion suggestion per line.
    /// * `denylist`:  One JSON deny suggestion per line.
    /// * `allowlist`:  One JSON allow suggestion per line.
    ///
    /// [google.cloud.retail.v2.BigQuerySource.data_schema]: crate::model::BigQuerySource::data_schema
    pub source: std::option::Option<crate::model::completion_data_input_config::Source>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CompletionDataInputConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [source][crate::model::CompletionDataInputConfig::source].
    ///
    /// Note that all the setters affecting `source` are mutually
    /// exclusive.
    pub fn set_source<
        T: std::convert::Into<std::option::Option<crate::model::completion_data_input_config::Source>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = v.into();
        self
    }

    /// The value of [source][crate::model::CompletionDataInputConfig::source]
    /// if it holds a `BigQuerySource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn big_query_source(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::BigQuerySource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::completion_data_input_config::Source::BigQuerySource(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::CompletionDataInputConfig::source]
    /// to hold a `BigQuerySource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_big_query_source<
        T: std::convert::Into<std::boxed::Box<crate::model::BigQuerySource>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = std::option::Option::Some(
            crate::model::completion_data_input_config::Source::BigQuerySource(v.into()),
        );
        self
    }
}

impl wkt::message::Message for CompletionDataInputConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CompletionDataInputConfig"
    }
}

/// Defines additional types related to [CompletionDataInputConfig].
pub mod completion_data_input_config {
    #[allow(unused_imports)]
    use super::*;

    /// The source of the input.
    ///
    /// Supported
    /// [BigQuerySource.data_schema][google.cloud.retail.v2.BigQuerySource.data_schema]
    /// values for suggestions imports:
    ///
    /// * `suggestions` (default): One JSON completion suggestion per line.
    /// * `denylist`:  One JSON deny suggestion per line.
    /// * `allowlist`:  One JSON allow suggestion per line.
    ///
    /// [google.cloud.retail.v2.BigQuerySource.data_schema]: crate::model::BigQuerySource::data_schema
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Source {
        /// Required. BigQuery input source.
        ///
        /// Add the IAM permission "BigQuery Data Viewer" for
        /// cloud-retail-customer-data-access@system.gserviceaccount.com before
        /// using this feature otherwise an error is thrown.
        BigQuerySource(std::boxed::Box<crate::model::BigQuerySource>),
    }
}

/// Metadata related to the progress of the Import operation. This is
/// returned by the google.longrunning.Operation.metadata field.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportMetadata {
    /// Operation create time.
    pub create_time: std::option::Option<wkt::Timestamp>,

    /// Operation last update time. If the operation is done, this is also the
    /// finish time.
    pub update_time: std::option::Option<wkt::Timestamp>,

    /// Count of entries that were processed successfully.
    pub success_count: i64,

    /// Count of entries that encountered errors while processing.
    pub failure_count: i64,

    /// Deprecated. This field is never set.
    #[deprecated]
    pub request_id: std::string::String,

    /// Pub/Sub topic for receiving notification. If this field is set,
    /// when the import is finished, a notification is sent to
    /// specified Pub/Sub topic. The message data is JSON string of a
    /// [Operation][google.longrunning.Operation].
    /// Format of the Pub/Sub topic is `projects/{project}/topics/{topic}`.
    ///
    /// [google.longrunning.Operation]: longrunning::model::Operation
    pub notification_pubsub_topic: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [create_time][crate::model::ImportMetadata::create_time].
    pub fn set_create_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [create_time][crate::model::ImportMetadata::create_time].
    pub fn set_or_clear_create_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_time][crate::model::ImportMetadata::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::ImportMetadata::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [success_count][crate::model::ImportMetadata::success_count].
    pub fn set_success_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.success_count = v.into();
        self
    }

    /// Sets the value of [failure_count][crate::model::ImportMetadata::failure_count].
    pub fn set_failure_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.failure_count = v.into();
        self
    }

    /// Sets the value of [request_id][crate::model::ImportMetadata::request_id].
    #[deprecated]
    pub fn set_request_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.request_id = v.into();
        self
    }

    /// Sets the value of [notification_pubsub_topic][crate::model::ImportMetadata::notification_pubsub_topic].
    pub fn set_notification_pubsub_topic<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.notification_pubsub_topic = v.into();
        self
    }
}

impl wkt::message::Message for ImportMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportMetadata"
    }
}

/// Response of the
/// [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. If the
/// long running operation is done, then this message is returned by the
/// google.longrunning.Operations.response field if the operation was successful.
///
/// [google.cloud.retail.v2.ImportProductsRequest]: crate::model::ImportProductsRequest
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportProductsResponse {
    /// A sample of errors encountered while processing the request.
    pub error_samples: std::vec::Vec<rpc::model::Status>,

    /// Echoes the destination for the complete errors in the request if set.
    pub errors_config: std::option::Option<crate::model::ImportErrorsConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportProductsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [error_samples][crate::model::ImportProductsResponse::error_samples].
    pub fn set_error_samples<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.error_samples = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [errors_config][crate::model::ImportProductsResponse::errors_config].
    pub fn set_errors_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [errors_config][crate::model::ImportProductsResponse::errors_config].
    pub fn set_or_clear_errors_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ImportProductsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportProductsResponse"
    }
}

/// Response of the ImportUserEventsRequest. If the long running
/// operation was successful, then this message is returned by the
/// google.longrunning.Operations.response field if the operation was successful.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportUserEventsResponse {
    /// A sample of errors encountered while processing the request.
    pub error_samples: std::vec::Vec<rpc::model::Status>,

    /// Echoes the destination for the complete errors if this field was set in
    /// the request.
    pub errors_config: std::option::Option<crate::model::ImportErrorsConfig>,

    /// Aggregated statistics of user event import status.
    pub import_summary: std::option::Option<crate::model::UserEventImportSummary>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportUserEventsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [error_samples][crate::model::ImportUserEventsResponse::error_samples].
    pub fn set_error_samples<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.error_samples = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [errors_config][crate::model::ImportUserEventsResponse::errors_config].
    pub fn set_errors_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [errors_config][crate::model::ImportUserEventsResponse::errors_config].
    pub fn set_or_clear_errors_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ImportErrorsConfig>,
    {
        self.errors_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [import_summary][crate::model::ImportUserEventsResponse::import_summary].
    pub fn set_import_summary<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserEventImportSummary>,
    {
        self.import_summary = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [import_summary][crate::model::ImportUserEventsResponse::import_summary].
    pub fn set_or_clear_import_summary<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserEventImportSummary>,
    {
        self.import_summary = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ImportUserEventsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportUserEventsResponse"
    }
}

/// A summary of import result. The UserEventImportSummary summarizes
/// the import status for user events.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UserEventImportSummary {
    /// Count of user events imported with complete existing catalog information.
    pub joined_events_count: i64,

    /// Count of user events imported, but with catalog information not found
    /// in the imported catalog.
    pub unjoined_events_count: i64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UserEventImportSummary {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [joined_events_count][crate::model::UserEventImportSummary::joined_events_count].
    pub fn set_joined_events_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.joined_events_count = v.into();
        self
    }

    /// Sets the value of [unjoined_events_count][crate::model::UserEventImportSummary::unjoined_events_count].
    pub fn set_unjoined_events_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.unjoined_events_count = v.into();
        self
    }
}

impl wkt::message::Message for UserEventImportSummary {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UserEventImportSummary"
    }
}

/// Response of the
/// [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest].
/// If the long running operation is done, this message is returned by the
/// google.longrunning.Operations.response field if the operation is successful.
///
/// [google.cloud.retail.v2.ImportCompletionDataRequest]: crate::model::ImportCompletionDataRequest
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ImportCompletionDataResponse {
    /// A sample of errors encountered while processing the request.
    pub error_samples: std::vec::Vec<rpc::model::Status>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ImportCompletionDataResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [error_samples][crate::model::ImportCompletionDataResponse::error_samples].
    pub fn set_error_samples<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.error_samples = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ImportCompletionDataResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ImportCompletionDataResponse"
    }
}

/// Metadata that describes the training and serving parameters of a
/// [Model][google.cloud.retail.v2.Model]. A
/// [Model][google.cloud.retail.v2.Model] can be associated with a
/// [ServingConfig][google.cloud.retail.v2.ServingConfig] and then queried
/// through the Predict API.
///
/// [google.cloud.retail.v2.Model]: crate::model::Model
/// [google.cloud.retail.v2.ServingConfig]: crate::model::ServingConfig
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Model {
    /// Required. The fully qualified resource name of the model.
    ///
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    /// catalog_id has char limit of 50.
    /// recommendation_model_id has char limit of 40.
    pub name: std::string::String,

    /// Required. The display name of the model.
    ///
    /// Should be human readable, used to display Recommendation Models in the
    /// Retail Cloud Console Dashboard. UTF-8 encoded string with limit of 1024
    /// characters.
    pub display_name: std::string::String,

    /// Optional. The training state that the model is in (e.g.
    /// `TRAINING` or `PAUSED`).
    ///
    /// Since part of the cost of running the service
    /// is frequency of training - this can be used to determine when to train
    /// model in order to control cost. If not specified: the default value for
    /// `CreateModel` method is `TRAINING`. The default value for
    /// `UpdateModel` method is to keep the state the same as before.
    pub training_state: crate::model::model::TrainingState,

    /// Output only. The serving state of the model: `ACTIVE`, `NOT_ACTIVE`.
    pub serving_state: crate::model::model::ServingState,

    /// Output only. Timestamp the Recommendation Model was created at.
    pub create_time: std::option::Option<wkt::Timestamp>,

    /// Output only. Timestamp the Recommendation Model was last updated. E.g.
    /// if a Recommendation Model was paused - this would be the time the pause was
    /// initiated.
    pub update_time: std::option::Option<wkt::Timestamp>,

    /// Required. The type of model e.g. `home-page`.
    ///
    /// Currently supported values: `recommended-for-you`, `others-you-may-like`,
    /// `frequently-bought-together`, `page-optimization`, `similar-items`,
    /// `buy-it-again`, `on-sale-items`, and `recently-viewed`(readonly value).
    ///
    /// This field together with
    /// [optimization_objective][google.cloud.retail.v2.Model.optimization_objective]
    /// describe model metadata to use to control model training and serving.
    /// See <https://cloud.google.com/retail/docs/models>
    /// for more details on what the model metadata control and which combination
    /// of parameters are valid. For invalid combinations of parameters (e.g. type
    /// = `frequently-bought-together` and optimization_objective = `ctr`), you
    /// receive an error 400 if you try to create/update a recommendation with
    /// this set of knobs.
    ///
    /// [google.cloud.retail.v2.Model.optimization_objective]: crate::model::Model::optimization_objective
    pub r#type: std::string::String,

    /// Optional. The optimization objective e.g. `cvr`.
    ///
    /// Currently supported
    /// values: `ctr`, `cvr`, `revenue-per-order`.
    ///
    /// If not specified, we choose default based on model type.
    /// Default depends on type of recommendation:
    ///
    /// `recommended-for-you` => `ctr`
    ///
    /// `others-you-may-like` => `ctr`
    ///
    /// `frequently-bought-together` => `revenue_per_order`
    ///
    /// This field together with
    /// [optimization_objective][google.cloud.retail.v2.Model.type]
    /// describe model metadata to use to control model training and serving.
    /// See <https://cloud.google.com/retail/docs/models>
    /// for more details on what the model metadata control and which combination
    /// of parameters are valid. For invalid combinations of parameters (e.g. type
    /// = `frequently-bought-together` and optimization_objective = `ctr`), you
    /// receive an error 400 if you try to create/update a recommendation with
    /// this set of knobs.
    ///
    /// [google.cloud.retail.v2.Model.type]: crate::model::Model::type
    pub optimization_objective: std::string::String,

    /// Optional. The state of periodic tuning.
    ///
    /// The period we use is 3 months - to do a
    /// one-off tune earlier use the `TuneModel` method. Default value
    /// is `PERIODIC_TUNING_ENABLED`.
    pub periodic_tuning_state: crate::model::model::PeriodicTuningState,

    /// Output only. The timestamp when the latest successful tune finished.
    pub last_tune_time: std::option::Option<wkt::Timestamp>,

    /// Output only. The tune operation associated with the model.
    ///
    /// Can be used to determine if there is an ongoing tune for this
    /// recommendation. Empty field implies no tune is goig on.
    pub tuning_operation: std::string::String,

    /// Output only. The state of data requirements for this model: `DATA_OK` and
    /// `DATA_ERROR`.
    ///
    /// Recommendation model cannot be trained if the data is in
    /// `DATA_ERROR` state. Recommendation model can have `DATA_ERROR` state even
    /// if serving state is `ACTIVE`: models were trained successfully before, but
    /// cannot be refreshed because model no longer has sufficient
    /// data for training.
    pub data_state: crate::model::model::DataState,

    /// Optional. If `RECOMMENDATIONS_FILTERING_ENABLED`, recommendation filtering
    /// by attributes is enabled for the model.
    pub filtering_option: crate::model::RecommendationsFilteringOption,

    /// Output only. The list of valid serving configs associated with the
    /// PageOptimizationConfig.
    pub serving_config_lists: std::vec::Vec<crate::model::model::ServingConfigList>,

    /// Optional. Additional model features config.
    pub model_features_config: std::option::Option<crate::model::model::ModelFeaturesConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Model {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::Model::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [display_name][crate::model::Model::display_name].
    pub fn set_display_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.display_name = v.into();
        self
    }

    /// Sets the value of [training_state][crate::model::Model::training_state].
    pub fn set_training_state<T: std::convert::Into<crate::model::model::TrainingState>>(
        mut self,
        v: T,
    ) -> Self {
        self.training_state = v.into();
        self
    }

    /// Sets the value of [serving_state][crate::model::Model::serving_state].
    pub fn set_serving_state<T: std::convert::Into<crate::model::model::ServingState>>(
        mut self,
        v: T,
    ) -> Self {
        self.serving_state = v.into();
        self
    }

    /// Sets the value of [create_time][crate::model::Model::create_time].
    pub fn set_create_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [create_time][crate::model::Model::create_time].
    pub fn set_or_clear_create_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_time][crate::model::Model::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::Model::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [r#type][crate::model::Model::type].
    pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [optimization_objective][crate::model::Model::optimization_objective].
    pub fn set_optimization_objective<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.optimization_objective = v.into();
        self
    }

    /// Sets the value of [periodic_tuning_state][crate::model::Model::periodic_tuning_state].
    pub fn set_periodic_tuning_state<
        T: std::convert::Into<crate::model::model::PeriodicTuningState>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.periodic_tuning_state = v.into();
        self
    }

    /// Sets the value of [last_tune_time][crate::model::Model::last_tune_time].
    pub fn set_last_tune_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.last_tune_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [last_tune_time][crate::model::Model::last_tune_time].
    pub fn set_or_clear_last_tune_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.last_tune_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [tuning_operation][crate::model::Model::tuning_operation].
    pub fn set_tuning_operation<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.tuning_operation = v.into();
        self
    }

    /// Sets the value of [data_state][crate::model::Model::data_state].
    pub fn set_data_state<T: std::convert::Into<crate::model::model::DataState>>(
        mut self,
        v: T,
    ) -> Self {
        self.data_state = v.into();
        self
    }

    /// Sets the value of [filtering_option][crate::model::Model::filtering_option].
    pub fn set_filtering_option<
        T: std::convert::Into<crate::model::RecommendationsFilteringOption>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.filtering_option = v.into();
        self
    }

    /// Sets the value of [serving_config_lists][crate::model::Model::serving_config_lists].
    pub fn set_serving_config_lists<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::model::ServingConfigList>,
    {
        use std::iter::Iterator;
        self.serving_config_lists = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [model_features_config][crate::model::Model::model_features_config].
    pub fn set_model_features_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::model::ModelFeaturesConfig>,
    {
        self.model_features_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [model_features_config][crate::model::Model::model_features_config].
    pub fn set_or_clear_model_features_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::model::ModelFeaturesConfig>,
    {
        self.model_features_config = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for Model {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Model"
    }
}

/// Defines additional types related to [Model].
pub mod model {
    #[allow(unused_imports)]
    use super::*;

    /// Represents an ordered combination of valid serving configs, which
    /// can be used for `PAGE_OPTIMIZATION` recommendations.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ServingConfigList {
        /// Optional. A set of valid serving configs that may be used for
        /// `PAGE_OPTIMIZATION`.
        pub serving_config_ids: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ServingConfigList {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [serving_config_ids][crate::model::model::ServingConfigList::serving_config_ids].
        pub fn set_serving_config_ids<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.serving_config_ids = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for ServingConfigList {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Model.ServingConfigList"
        }
    }

    /// Additional configs for the frequently-bought-together model type.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FrequentlyBoughtTogetherFeaturesConfig {
        /// Optional. Specifies the context of the model when it is used in predict
        /// requests. Can only be set for the `frequently-bought-together` type. If
        /// it isn't specified, it defaults to
        /// [MULTIPLE_CONTEXT_PRODUCTS][google.cloud.retail.v2.Model.ContextProductsType.MULTIPLE_CONTEXT_PRODUCTS].
        ///
        /// [google.cloud.retail.v2.Model.ContextProductsType.MULTIPLE_CONTEXT_PRODUCTS]: crate::model::model::ContextProductsType::MultipleContextProducts
        pub context_products_type: crate::model::model::ContextProductsType,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FrequentlyBoughtTogetherFeaturesConfig {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [context_products_type][crate::model::model::FrequentlyBoughtTogetherFeaturesConfig::context_products_type].
        pub fn set_context_products_type<
            T: std::convert::Into<crate::model::model::ContextProductsType>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.context_products_type = v.into();
            self
        }
    }

    impl wkt::message::Message for FrequentlyBoughtTogetherFeaturesConfig {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Model.FrequentlyBoughtTogetherFeaturesConfig"
        }
    }

    /// Additional model features config.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ModelFeaturesConfig {
        pub type_dedicated_config:
            std::option::Option<crate::model::model::model_features_config::TypeDedicatedConfig>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ModelFeaturesConfig {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [type_dedicated_config][crate::model::model::ModelFeaturesConfig::type_dedicated_config].
        ///
        /// Note that all the setters affecting `type_dedicated_config` are mutually
        /// exclusive.
        pub fn set_type_dedicated_config<
            T: std::convert::Into<
                    std::option::Option<
                        crate::model::model::model_features_config::TypeDedicatedConfig,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.type_dedicated_config = v.into();
            self
        }

        /// The value of [type_dedicated_config][crate::model::model::ModelFeaturesConfig::type_dedicated_config]
        /// if it holds a `FrequentlyBoughtTogetherConfig`, `None` if the field is not set or
        /// holds a different branch.
        pub fn frequently_bought_together_config(
            &self,
        ) -> std::option::Option<
            &std::boxed::Box<crate::model::model::FrequentlyBoughtTogetherFeaturesConfig>,
        > {
            #[allow(unreachable_patterns)]
            self.type_dedicated_config.as_ref().and_then(|v| match v {
                crate::model::model::model_features_config::TypeDedicatedConfig::FrequentlyBoughtTogetherConfig(v) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [type_dedicated_config][crate::model::model::ModelFeaturesConfig::type_dedicated_config]
        /// to hold a `FrequentlyBoughtTogetherConfig`.
        ///
        /// Note that all the setters affecting `type_dedicated_config` are
        /// mutually exclusive.
        pub fn set_frequently_bought_together_config<
            T: std::convert::Into<
                    std::boxed::Box<crate::model::model::FrequentlyBoughtTogetherFeaturesConfig>,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.type_dedicated_config = std::option::Option::Some(
                crate::model::model::model_features_config::TypeDedicatedConfig::FrequentlyBoughtTogetherConfig(
                    v.into()
                )
            );
            self
        }
    }

    impl wkt::message::Message for ModelFeaturesConfig {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.Model.ModelFeaturesConfig"
        }
    }

    /// Defines additional types related to [ModelFeaturesConfig].
    pub mod model_features_config {
        #[allow(unused_imports)]
        use super::*;

        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum TypeDedicatedConfig {
            /// Additional configs for frequently-bought-together models.
            FrequentlyBoughtTogetherConfig(
                std::boxed::Box<crate::model::model::FrequentlyBoughtTogetherFeaturesConfig>,
            ),
        }
    }

    /// The serving state of the model.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ServingState {
        /// Unspecified serving state.
        Unspecified,
        /// The model is not serving.
        Inactive,
        /// The model is serving and can be queried.
        Active,
        /// The model is trained on tuned hyperparameters and can be
        /// queried.
        Tuned,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [ServingState::value] or
        /// [ServingState::name].
        UnknownValue(serving_state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod serving_state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl ServingState {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Inactive => std::option::Option::Some(1),
                Self::Active => std::option::Option::Some(2),
                Self::Tuned => std::option::Option::Some(3),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("SERVING_STATE_UNSPECIFIED"),
                Self::Inactive => std::option::Option::Some("INACTIVE"),
                Self::Active => std::option::Option::Some("ACTIVE"),
                Self::Tuned => std::option::Option::Some("TUNED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for ServingState {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for ServingState {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for ServingState {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Inactive,
                2 => Self::Active,
                3 => Self::Tuned,
                _ => Self::UnknownValue(serving_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for ServingState {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "SERVING_STATE_UNSPECIFIED" => Self::Unspecified,
                "INACTIVE" => Self::Inactive,
                "ACTIVE" => Self::Active,
                "TUNED" => Self::Tuned,
                _ => Self::UnknownValue(serving_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for ServingState {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Inactive => serializer.serialize_i32(1),
                Self::Active => serializer.serialize_i32(2),
                Self::Tuned => serializer.serialize_i32(3),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for ServingState {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<ServingState>::new(
                ".google.cloud.retail.v2.Model.ServingState",
            ))
        }
    }

    /// The training state of the model.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum TrainingState {
        /// Unspecified training state.
        Unspecified,
        /// The model training is paused.
        Paused,
        /// The model is training.
        Training,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [TrainingState::value] or
        /// [TrainingState::name].
        UnknownValue(training_state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod training_state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl TrainingState {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Paused => std::option::Option::Some(1),
                Self::Training => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("TRAINING_STATE_UNSPECIFIED"),
                Self::Paused => std::option::Option::Some("PAUSED"),
                Self::Training => std::option::Option::Some("TRAINING"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for TrainingState {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for TrainingState {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for TrainingState {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Paused,
                2 => Self::Training,
                _ => Self::UnknownValue(training_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for TrainingState {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "TRAINING_STATE_UNSPECIFIED" => Self::Unspecified,
                "PAUSED" => Self::Paused,
                "TRAINING" => Self::Training,
                _ => Self::UnknownValue(training_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for TrainingState {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Paused => serializer.serialize_i32(1),
                Self::Training => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for TrainingState {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<TrainingState>::new(
                ".google.cloud.retail.v2.Model.TrainingState",
            ))
        }
    }

    /// Describes whether periodic tuning is enabled for this model
    /// or not. Periodic tuning is scheduled at most every three months. You can
    /// start a tuning process manually by using the `TuneModel`
    /// method, which starts a tuning process immediately and resets the quarterly
    /// schedule. Enabling or disabling periodic tuning does not affect any
    /// current tuning processes.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum PeriodicTuningState {
        /// Unspecified default value, should never be explicitly set.
        Unspecified,
        /// The model has periodic tuning disabled. Tuning
        /// can be reenabled by calling the `EnableModelPeriodicTuning`
        /// method or by calling the `TuneModel` method.
        PeriodicTuningDisabled,
        /// The model cannot be tuned with periodic tuning OR the
        /// `TuneModel` method. Hide the options in customer UI and
        /// reject any requests through the backend self serve API.
        AllTuningDisabled,
        /// The model has periodic tuning enabled. Tuning
        /// can be disabled by calling the `DisableModelPeriodicTuning`
        /// method.
        PeriodicTuningEnabled,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [PeriodicTuningState::value] or
        /// [PeriodicTuningState::name].
        UnknownValue(periodic_tuning_state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod periodic_tuning_state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl PeriodicTuningState {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::PeriodicTuningDisabled => std::option::Option::Some(1),
                Self::AllTuningDisabled => std::option::Option::Some(3),
                Self::PeriodicTuningEnabled => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("PERIODIC_TUNING_STATE_UNSPECIFIED"),
                Self::PeriodicTuningDisabled => {
                    std::option::Option::Some("PERIODIC_TUNING_DISABLED")
                }
                Self::AllTuningDisabled => std::option::Option::Some("ALL_TUNING_DISABLED"),
                Self::PeriodicTuningEnabled => std::option::Option::Some("PERIODIC_TUNING_ENABLED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for PeriodicTuningState {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for PeriodicTuningState {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for PeriodicTuningState {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::PeriodicTuningDisabled,
                2 => Self::PeriodicTuningEnabled,
                3 => Self::AllTuningDisabled,
                _ => Self::UnknownValue(periodic_tuning_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for PeriodicTuningState {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "PERIODIC_TUNING_STATE_UNSPECIFIED" => Self::Unspecified,
                "PERIODIC_TUNING_DISABLED" => Self::PeriodicTuningDisabled,
                "ALL_TUNING_DISABLED" => Self::AllTuningDisabled,
                "PERIODIC_TUNING_ENABLED" => Self::PeriodicTuningEnabled,
                _ => Self::UnknownValue(periodic_tuning_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for PeriodicTuningState {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::PeriodicTuningDisabled => serializer.serialize_i32(1),
                Self::AllTuningDisabled => serializer.serialize_i32(3),
                Self::PeriodicTuningEnabled => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for PeriodicTuningState {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<PeriodicTuningState>::new(
                ".google.cloud.retail.v2.Model.PeriodicTuningState",
            ))
        }
    }

    /// Describes whether this model have sufficient training data
    /// to be continuously trained.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum DataState {
        /// Unspecified default value, should never be explicitly set.
        Unspecified,
        /// The model has sufficient training data.
        DataOk,
        /// The model does not have sufficient training data. Error
        /// messages can be queried via Stackdriver.
        DataError,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [DataState::value] or
        /// [DataState::name].
        UnknownValue(data_state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod data_state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl DataState {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::DataOk => std::option::Option::Some(1),
                Self::DataError => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("DATA_STATE_UNSPECIFIED"),
                Self::DataOk => std::option::Option::Some("DATA_OK"),
                Self::DataError => std::option::Option::Some("DATA_ERROR"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for DataState {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for DataState {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for DataState {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::DataOk,
                2 => Self::DataError,
                _ => Self::UnknownValue(data_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for DataState {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "DATA_STATE_UNSPECIFIED" => Self::Unspecified,
                "DATA_OK" => Self::DataOk,
                "DATA_ERROR" => Self::DataError,
                _ => Self::UnknownValue(data_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for DataState {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::DataOk => serializer.serialize_i32(1),
                Self::DataError => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for DataState {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<DataState>::new(
                ".google.cloud.retail.v2.Model.DataState",
            ))
        }
    }

    /// Use single or multiple context products for recommendations.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ContextProductsType {
        /// Unspecified default value, should never be explicitly set.
        /// Defaults to
        /// [MULTIPLE_CONTEXT_PRODUCTS][google.cloud.retail.v2.Model.ContextProductsType.MULTIPLE_CONTEXT_PRODUCTS].
        ///
        /// [google.cloud.retail.v2.Model.ContextProductsType.MULTIPLE_CONTEXT_PRODUCTS]: crate::model::model::ContextProductsType::MultipleContextProducts
        Unspecified,
        /// Use only a single product as context for the recommendation. Typically
        /// used on pages like add-to-cart or product details.
        SingleContextProduct,
        /// Use one or multiple products as context for the recommendation. Typically
        /// used on shopping cart pages.
        MultipleContextProducts,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [ContextProductsType::value] or
        /// [ContextProductsType::name].
        UnknownValue(context_products_type::UnknownValue),
    }

    #[doc(hidden)]
    pub mod context_products_type {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl ContextProductsType {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::SingleContextProduct => std::option::Option::Some(1),
                Self::MultipleContextProducts => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("CONTEXT_PRODUCTS_TYPE_UNSPECIFIED"),
                Self::SingleContextProduct => std::option::Option::Some("SINGLE_CONTEXT_PRODUCT"),
                Self::MultipleContextProducts => {
                    std::option::Option::Some("MULTIPLE_CONTEXT_PRODUCTS")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for ContextProductsType {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for ContextProductsType {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for ContextProductsType {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::SingleContextProduct,
                2 => Self::MultipleContextProducts,
                _ => Self::UnknownValue(context_products_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for ContextProductsType {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "CONTEXT_PRODUCTS_TYPE_UNSPECIFIED" => Self::Unspecified,
                "SINGLE_CONTEXT_PRODUCT" => Self::SingleContextProduct,
                "MULTIPLE_CONTEXT_PRODUCTS" => Self::MultipleContextProducts,
                _ => Self::UnknownValue(context_products_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for ContextProductsType {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::SingleContextProduct => serializer.serialize_i32(1),
                Self::MultipleContextProducts => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for ContextProductsType {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<ContextProductsType>::new(
                ".google.cloud.retail.v2.Model.ContextProductsType",
            ))
        }
    }
}

/// Request for creating a model.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CreateModelRequest {
    /// Required. The parent resource under which to create the model. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`
    pub parent: std::string::String,

    /// Required. The payload of the [Model][google.cloud.retail.v2.Model]  to
    /// create.
    ///
    /// [google.cloud.retail.v2.Model]: crate::model::Model
    pub model: std::option::Option<crate::model::Model>,

    /// Optional. Whether to run a dry run to validate the request (without
    /// actually creating the model).
    pub dry_run: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CreateModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::CreateModelRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [model][crate::model::CreateModelRequest::model].
    pub fn set_model<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Model>,
    {
        self.model = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [model][crate::model::CreateModelRequest::model].
    pub fn set_or_clear_model<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Model>,
    {
        self.model = v.map(|x| x.into());
        self
    }

    /// Sets the value of [dry_run][crate::model::CreateModelRequest::dry_run].
    pub fn set_dry_run<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.dry_run = v.into();
        self
    }
}

impl wkt::message::Message for CreateModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CreateModelRequest"
    }
}

/// Request for updating an existing model.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateModelRequest {
    /// Required. The body of the updated [Model][google.cloud.retail.v2.Model].
    ///
    /// [google.cloud.retail.v2.Model]: crate::model::Model
    pub model: std::option::Option<crate::model::Model>,

    /// Optional. Indicates which fields in the provided 'model' to
    /// update. If not set, by default updates all fields.
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [model][crate::model::UpdateModelRequest::model].
    pub fn set_model<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Model>,
    {
        self.model = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [model][crate::model::UpdateModelRequest::model].
    pub fn set_or_clear_model<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Model>,
    {
        self.model = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateModelRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateModelRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateModelRequest"
    }
}

/// Request for getting a model.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetModelRequest {
    /// Required. The resource name of the [Model][google.cloud.retail.v2.Model] to
    /// get. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`
    ///
    /// [google.cloud.retail.v2.Model]: crate::model::Model
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetModelRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for GetModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetModelRequest"
    }
}

/// Request for pausing training of a model.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PauseModelRequest {
    /// Required. The name of the model to pause.
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PauseModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::PauseModelRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for PauseModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PauseModelRequest"
    }
}

/// Request for resuming training of a model.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ResumeModelRequest {
    /// Required. The name of the model to resume.
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ResumeModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::ResumeModelRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for ResumeModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ResumeModelRequest"
    }
}

/// Request for listing models associated with a resource.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListModelsRequest {
    /// Required. The parent for which to list models.
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`
    pub parent: std::string::String,

    /// Optional. Maximum number of results to return. If unspecified, defaults
    /// to 50. Max allowed value is 1000.
    pub page_size: i32,

    /// Optional. A page token, received from a previous `ListModels`
    /// call. Provide this to retrieve the subsequent page.
    pub page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListModelsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListModelsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListModelsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListModelsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListModelsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListModelsRequest"
    }
}

/// Request for deleting a model.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DeleteModelRequest {
    /// Required. The resource name of the [Model][google.cloud.retail.v2.Model] to
    /// delete. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    ///
    /// [google.cloud.retail.v2.Model]: crate::model::Model
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DeleteModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::DeleteModelRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for DeleteModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.DeleteModelRequest"
    }
}

/// Response to a ListModelRequest.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListModelsResponse {
    /// List of Models.
    pub models: std::vec::Vec<crate::model::Model>,

    /// Pagination token, if not returned indicates the last page.
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListModelsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [models][crate::model::ListModelsResponse::models].
    pub fn set_models<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Model>,
    {
        use std::iter::Iterator;
        self.models = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListModelsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListModelsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListModelsResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for ListModelsResponse {
    type PageItem = crate::model::Model;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.models
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// Request to manually start a tuning process now (instead of waiting for
/// the periodically scheduled tuning to happen).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TuneModelRequest {
    /// Required. The resource name of the model to tune.
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TuneModelRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::TuneModelRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for TuneModelRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.TuneModelRequest"
    }
}

/// Metadata associated with a create operation.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CreateModelMetadata {
    /// The resource name of the model that this create applies to.
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    pub model: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CreateModelMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [model][crate::model::CreateModelMetadata::model].
    pub fn set_model<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.model = v.into();
        self
    }
}

impl wkt::message::Message for CreateModelMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CreateModelMetadata"
    }
}

/// Metadata associated with a tune operation.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TuneModelMetadata {
    /// The resource name of the model that this tune applies to.
    /// Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`
    pub model: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TuneModelMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [model][crate::model::TuneModelMetadata::model].
    pub fn set_model<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.model = v.into();
        self
    }
}

impl wkt::message::Message for TuneModelMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.TuneModelMetadata"
    }
}

/// Response associated with a tune operation.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TuneModelResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TuneModelResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for TuneModelResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.TuneModelResponse"
    }
}

/// Request message for Predict method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PredictRequest {
    /// Required. Full resource name of the format:
    /// `{placement=projects/*/locations/global/catalogs/default_catalog/servingConfigs/*}`
    /// or
    /// `{placement=projects/*/locations/global/catalogs/default_catalog/placements/*}`.
    /// We recommend using the `servingConfigs` resource. `placements` is a legacy
    /// resource.
    /// The ID of the Recommendations AI serving config or placement.
    /// Before you can request predictions from your model, you must create at
    /// least one serving config or placement for it. For more information, see
    /// [Manage serving configs]
    /// (<https://cloud.google.com/retail/docs/manage-configs>).
    ///
    /// The full list of available serving configs can be seen at
    /// <https://console.cloud.google.com/ai/retail/catalogs/default_catalog/configs>
    pub placement: std::string::String,

    /// Required. Context about the user, what they are looking at and what action
    /// they took to trigger the predict request. Note that this user event detail
    /// won't be ingested to userEvent logs. Thus, a separate userEvent write
    /// request is required for event logging.
    ///
    /// Don't set
    /// [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id] or
    /// [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id] to the same
    /// fixed ID for different users. If you are trying to receive non-personalized
    /// recommendations (not recommended; this can negatively impact model
    /// performance), instead set
    /// [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id] to a
    /// random unique ID and leave
    /// [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id] unset.
    ///
    /// [google.cloud.retail.v2.UserEvent.visitor_id]: crate::model::UserEvent::visitor_id
    /// [google.cloud.retail.v2.UserInfo.user_id]: crate::model::UserInfo::user_id
    pub user_event: std::option::Option<crate::model::UserEvent>,

    /// Maximum number of results to return. Set this property to the number of
    /// prediction results needed. If zero, the service will choose a reasonable
    /// default. The maximum allowed value is 100. Values above 100 will be coerced
    /// to 100.
    pub page_size: i32,

    /// This field is not used; leave it unset.
    #[deprecated]
    pub page_token: std::string::String,

    /// Filter for restricting prediction results with a length limit of 5,000
    /// characters. Accepts values for tags and the `filterOutOfStockItems` flag.
    ///
    /// * Tag expressions. Restricts predictions to products that match all of the
    ///   specified tags. Boolean operators `OR` and `NOT` are supported if the
    ///   expression is enclosed in parentheses, and must be separated from the
    ///   tag values by a space. `-"tagA"` is also supported and is equivalent to
    ///   `NOT "tagA"`. Tag values must be double quoted UTF-8 encoded strings
    ///   with a size limit of 1,000 characters.
    ///
    ///   Note: "Recently viewed" models don't support tag filtering at the
    ///   moment.
    ///
    /// * filterOutOfStockItems. Restricts predictions to products that do not
    ///   have a
    ///   stockState value of OUT_OF_STOCK.
    ///
    ///
    /// Examples:
    ///
    /// * tag=("Red" OR "Blue") tag="New-Arrival" tag=(NOT "promotional")
    /// * filterOutOfStockItems  tag=(-"promotional")
    /// * filterOutOfStockItems
    ///
    /// If your filter blocks all prediction results, the API will return *no*
    /// results. If instead you want empty result sets to return generic
    /// (unfiltered) popular products, set `strictFiltering` to False in
    /// `PredictRequest.params`. Note that the API will never return items with
    /// storageStatus of "EXPIRED" or "DELETED" regardless of filter choices.
    ///
    /// If `filterSyntaxV2` is set to true under the `params` field, then
    /// attribute-based expressions are expected instead of the above described
    /// tag-based syntax. Examples:
    ///
    /// * (colors: ANY("Red", "Blue")) AND NOT (categories: ANY("Phones"))
    /// * (availability: ANY("IN_STOCK")) AND
    ///   (colors: ANY("Red") OR categories: ANY("Phones"))
    ///
    /// For more information, see
    /// [Filter recommendations](https://cloud.google.com/retail/docs/filter-recs).
    pub filter: std::string::String,

    /// Use validate only mode for this prediction query. If set to true, a
    /// dummy model will be used that returns arbitrary products.
    /// Note that the validate only mode should only be used for testing the API,
    /// or if the model is not ready.
    pub validate_only: bool,

    /// Additional domain specific parameters for the predictions.
    ///
    /// Allowed values:
    ///
    /// * `returnProduct`: Boolean. If set to true, the associated product
    ///   object will be returned in the `results.metadata` field in the
    ///   prediction response.
    /// * `returnScore`: Boolean. If set to true, the prediction 'score'
    ///   corresponding to each returned product will be set in the
    ///   `results.metadata` field in the prediction response. The given
    ///   'score' indicates the probability of a product being clicked/purchased
    ///   given the user's context and history.
    /// * `strictFiltering`: Boolean. True by default. If set to false, the service
    ///   will return generic (unfiltered) popular products instead of empty if
    ///   your filter blocks all prediction results.
    /// * `priceRerankLevel`: String. Default empty. If set to be non-empty, then
    ///   it needs to be one of {'no-price-reranking', 'low-price-reranking',
    ///   'medium-price-reranking', 'high-price-reranking'}. This gives
    ///   request-level control and adjusts prediction results based on product
    ///   price.
    /// * `diversityLevel`: String. Default empty. If set to be non-empty, then
    ///   it needs to be one of {'no-diversity', 'low-diversity',
    ///   'medium-diversity', 'high-diversity', 'auto-diversity'}. This gives
    ///   request-level control and adjusts prediction results based on product
    ///   category.
    /// * `filterSyntaxV2`: Boolean. False by default. If set to true, the `filter`
    ///   field is interpreteted according to the new, attribute-based syntax.
    pub params: std::collections::HashMap<std::string::String, wkt::Value>,

    /// The labels applied to a resource must meet the following requirements:
    ///
    /// * Each resource can have multiple labels, up to a maximum of 64.
    /// * Each label must be a key-value pair.
    /// * Keys have a minimum length of 1 character and a maximum length of 63
    ///   characters and cannot be empty. Values can be empty and have a maximum
    ///   length of 63 characters.
    /// * Keys and values can contain only lowercase letters, numeric characters,
    ///   underscores, and dashes. All characters must use UTF-8 encoding, and
    ///   international characters are allowed.
    /// * The key portion of a label must be unique. However, you can use the same
    ///   key with multiple resources.
    /// * Keys must start with a lowercase letter or international character.
    ///
    /// See [Google Cloud
    /// Document](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements)
    /// for more details.
    pub labels: std::collections::HashMap<std::string::String, std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PredictRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [placement][crate::model::PredictRequest::placement].
    pub fn set_placement<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.placement = v.into();
        self
    }

    /// Sets the value of [user_event][crate::model::PredictRequest::user_event].
    pub fn set_user_event<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserEvent>,
    {
        self.user_event = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [user_event][crate::model::PredictRequest::user_event].
    pub fn set_or_clear_user_event<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserEvent>,
    {
        self.user_event = v.map(|x| x.into());
        self
    }

    /// Sets the value of [page_size][crate::model::PredictRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::PredictRequest::page_token].
    #[deprecated]
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::PredictRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }

    /// Sets the value of [validate_only][crate::model::PredictRequest::validate_only].
    pub fn set_validate_only<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.validate_only = v.into();
        self
    }

    /// Sets the value of [params][crate::model::PredictRequest::params].
    pub fn set_params<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<wkt::Value>,
    {
        use std::iter::Iterator;
        self.params = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [labels][crate::model::PredictRequest::labels].
    pub fn set_labels<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.labels = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for PredictRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PredictRequest"
    }
}

/// Response message for predict method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PredictResponse {
    /// A list of recommended products. The order represents the ranking (from the
    /// most relevant product to the least).
    pub results: std::vec::Vec<crate::model::predict_response::PredictionResult>,

    /// A unique attribution token. This should be included in the
    /// [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting from this
    /// recommendation, which enables accurate attribution of recommendation model
    /// performance.
    ///
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    pub attribution_token: std::string::String,

    /// IDs of products in the request that were missing from the inventory.
    pub missing_ids: std::vec::Vec<std::string::String>,

    /// True if the validateOnly property was set in the request.
    pub validate_only: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PredictResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [results][crate::model::PredictResponse::results].
    pub fn set_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::predict_response::PredictionResult>,
    {
        use std::iter::Iterator;
        self.results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [attribution_token][crate::model::PredictResponse::attribution_token].
    pub fn set_attribution_token<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attribution_token = v.into();
        self
    }

    /// Sets the value of [missing_ids][crate::model::PredictResponse::missing_ids].
    pub fn set_missing_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.missing_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [validate_only][crate::model::PredictResponse::validate_only].
    pub fn set_validate_only<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.validate_only = v.into();
        self
    }
}

impl wkt::message::Message for PredictResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PredictResponse"
    }
}

/// Defines additional types related to [PredictResponse].
pub mod predict_response {
    #[allow(unused_imports)]
    use super::*;

    /// PredictionResult represents the recommendation prediction results.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct PredictionResult {
        /// ID of the recommended product
        pub id: std::string::String,

        /// Additional product metadata / annotations.
        ///
        /// Possible values:
        ///
        /// * `product`: JSON representation of the product. Is set if
        ///   `returnProduct` is set to true in `PredictRequest.params`.
        /// * `score`: Prediction score in double value. Is set if
        ///   `returnScore` is set to true in `PredictRequest.params`.
        pub metadata: std::collections::HashMap<std::string::String, wkt::Value>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl PredictionResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [id][crate::model::predict_response::PredictionResult::id].
        pub fn set_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.id = v.into();
            self
        }

        /// Sets the value of [metadata][crate::model::predict_response::PredictionResult::metadata].
        pub fn set_metadata<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<wkt::Value>,
        {
            use std::iter::Iterator;
            self.metadata = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }
    }

    impl wkt::message::Message for PredictionResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.PredictResponse.PredictionResult"
        }
    }
}

/// Product captures all metadata information of items to be recommended or
/// searched.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Product {
    /// Immutable. Full resource name of the product, such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/product_id`.
    pub name: std::string::String,

    /// Immutable. [Product][google.cloud.retail.v2.Product] identifier, which is
    /// the final component of [name][google.cloud.retail.v2.Product.name]. For
    /// example, this field is "id_1", if
    /// [name][google.cloud.retail.v2.Product.name] is
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/id_1`.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [id](https://support.google.com/merchants/answer/6324405). Schema.org
    /// property [Product.sku](https://schema.org/sku).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
    pub id: std::string::String,

    /// Immutable. The type of the product. Default to
    /// [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type]
    /// if unset.
    ///
    /// [google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type]: crate::model::ProductLevelConfig::ingestion_product_type
    pub r#type: crate::model::product::Type,

    /// Variant group identifier. Must be an
    /// [id][google.cloud.retail.v2.Product.id], with the same parent branch with
    /// this product. Otherwise, an error is thrown.
    ///
    /// For [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product]s, this field can only be empty or
    /// set to the same value as [id][google.cloud.retail.v2.Product.id].
    ///
    /// For VARIANT [Product][google.cloud.retail.v2.Product]s, this field cannot
    /// be empty. A maximum of 2,000 products are allowed to share the same
    /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product]. Otherwise, an INVALID_ARGUMENT
    /// error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [item_group_id](https://support.google.com/merchants/answer/6324507).
    /// Schema.org property
    /// [Product.inProductGroupWithID](https://schema.org/inProductGroupWithID).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    pub primary_product_id: std::string::String,

    /// The [id][google.cloud.retail.v2.Product.id] of the collection members when
    /// [type][google.cloud.retail.v2.Product.type] is
    /// [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION].
    ///
    /// Non-existent product ids are allowed.
    /// The [type][google.cloud.retail.v2.Product.type] of the members must be
    /// either [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] or
    /// [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] otherwise an
    /// INVALID_ARGUMENT error is thrown. Should not set it for other types. A
    /// maximum of 1000 values are allowed. Otherwise, an INVALID_ARGUMENT error is
    /// return.
    ///
    /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    /// [google.cloud.retail.v2.Product.type]: crate::model::Product::type
    pub collection_member_ids: std::vec::Vec<std::string::String>,

    /// The Global Trade Item Number (GTIN) of the product.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// This field must be a Unigram. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [gtin](https://support.google.com/merchants/answer/6324461).
    /// Schema.org property
    /// [Product.isbn](https://schema.org/isbn),
    /// [Product.gtin8](https://schema.org/gtin8),
    /// [Product.gtin12](https://schema.org/gtin12),
    /// [Product.gtin13](https://schema.org/gtin13), or
    /// [Product.gtin14](https://schema.org/gtin14).
    ///
    /// If the value is not a valid GTIN, an INVALID_ARGUMENT error is returned.
    pub gtin: std::string::String,

    /// Product categories. This field is repeated for supporting one product
    /// belonging to several parallel categories. Strongly recommended using the
    /// full path for better search / recommendation quality.
    ///
    /// To represent full path of category, use '>' sign to separate different
    /// hierarchies. If '>' is part of the category name, replace it with
    /// other character(s).
    ///
    /// For example, if a shoes product belongs to both
    /// ["Shoes & Accessories" -> "Shoes"] and
    /// ["Sports & Fitness" -> "Athletic Clothing" -> "Shoes"], it could be
    /// represented as:
    ///
    /// ```norust
    ///  "categories": [
    ///    "Shoes & Accessories > Shoes",
    ///    "Sports & Fitness > Athletic Clothing > Shoes"
    ///  ]
    /// ```
    ///
    /// Must be set for [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product] otherwise an INVALID_ARGUMENT
    /// error is returned.
    ///
    /// At most 250 values are allowed per
    /// [Product][google.cloud.retail.v2.Product] unless overridden through the
    /// Google Cloud console. Empty values are not allowed. Each value must be a
    /// UTF-8 encoded string with a length limit of 5,000 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [google_product_category][mc_google_product_category]. Schema.org property
    /// [Product.category] (<https://schema.org/category>).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    pub categories: std::vec::Vec<std::string::String>,

    /// Required. Product title.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 1,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [title](https://support.google.com/merchants/answer/6324415). Schema.org
    /// property [Product.name](https://schema.org/name).
    pub title: std::string::String,

    /// The brands of the product.
    ///
    /// A maximum of 30 brands are allowed unless overridden through the Google
    /// Cloud console. Each
    /// brand must be a UTF-8 encoded string with a length limit of 1,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [brand](https://support.google.com/merchants/answer/6324351). Schema.org
    /// property [Product.brand](https://schema.org/brand).
    pub brands: std::vec::Vec<std::string::String>,

    /// Product description.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 5,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [description](https://support.google.com/merchants/answer/6324468).
    /// Schema.org property [Product.description](https://schema.org/description).
    pub description: std::string::String,

    /// Language of the title/description and other string attributes. Use language
    /// tags defined by [BCP 47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt).
    ///
    /// For product prediction, this field is ignored and the model automatically
    /// detects the text language. The [Product][google.cloud.retail.v2.Product]
    /// can include text in different languages, but duplicating
    /// [Product][google.cloud.retail.v2.Product]s to provide text in multiple
    /// languages can result in degraded model performance.
    ///
    /// For product search this field is in use. It defaults to "en-US" if unset.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub language_code: std::string::String,

    /// Highly encouraged. Extra product attributes to be included. For example,
    /// for products, this could include the store name, vendor, style, color, etc.
    /// These are very strong signals for recommendation model, thus we highly
    /// recommend providing the attributes here.
    ///
    /// Features that can take on one of a limited number of possible values. Two
    /// types of features can be set are:
    ///
    /// Textual features. some examples would be the brand/maker of a product, or
    /// country of a customer. Numerical features. Some examples would be the
    /// height/weight of a product, or age of a customer.
    ///
    /// For example: `{ "vendor": {"text": ["vendor123", "vendor456"]},
    /// "lengths_cm": {"numbers":[2.3, 15.4]}, "heights_cm": {"numbers":[8.1, 6.4]}
    /// }`.
    ///
    /// This field needs to pass all below criteria, otherwise an INVALID_ARGUMENT
    /// error is returned:
    ///
    /// * Max entries count: 200.
    /// * The key must be a UTF-8 encoded string with a length limit of 128
    ///   characters.
    /// * For indexable attribute, the key must match the pattern:
    ///   `[a-zA-Z0-9][a-zA-Z0-9_]*`. For example, `key0LikeThis` or
    ///   `KEY_1_LIKE_THIS`.
    /// * For text attributes, at most 400 values are allowed. Empty values are not
    ///   allowed. Each value must be a non-empty UTF-8 encoded string with a
    ///   length limit of 256 characters.
    /// * For number attributes, at most 400 values are allowed.
    pub attributes: std::collections::HashMap<std::string::String, crate::model::CustomAttribute>,

    /// Custom tags associated with the product.
    ///
    /// At most 250 values are allowed per
    /// [Product][google.cloud.retail.v2.Product]. This value must be a UTF-8
    /// encoded string with a length limit of 1,000 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// This tag can be used for filtering recommendation results by passing the
    /// tag as part of the
    /// [PredictRequest.filter][google.cloud.retail.v2.PredictRequest.filter].
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [custom_label_0–4](https://support.google.com/merchants/answer/6324473).
    ///
    /// [google.cloud.retail.v2.PredictRequest.filter]: crate::model::PredictRequest::filter
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub tags: std::vec::Vec<std::string::String>,

    /// Product price and cost information.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [price](https://support.google.com/merchants/answer/6324371).
    pub price_info: std::option::Option<crate::model::PriceInfo>,

    /// The rating of this product.
    pub rating: std::option::Option<crate::model::Rating>,

    /// The timestamp when this [Product][google.cloud.retail.v2.Product] becomes
    /// available for
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. Note
    /// that this is only applicable to
    /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] and
    /// [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], and
    /// ignored for [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT].
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    pub available_time: std::option::Option<wkt::Timestamp>,

    /// The online availability of the [Product][google.cloud.retail.v2.Product].
    /// Default to
    /// [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK].
    ///
    /// For primary products with variants set the availability of the primary as
    /// [Availability.OUT_OF_STOCK][google.cloud.retail.v2.Product.Availability.OUT_OF_STOCK]
    /// and set the true availability at the variant level. This way the primary
    /// product will be considered "in stock" as long as it has at least one
    /// variant in stock.
    ///
    /// For primary products with no variants set the true availability at the
    /// primary level.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [availability](https://support.google.com/merchants/answer/6324448).
    /// Schema.org property [Offer.availability](https://schema.org/availability).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Availability.IN_STOCK]: crate::model::product::Availability::InStock
    /// [google.cloud.retail.v2.Product.Availability.OUT_OF_STOCK]: crate::model::product::Availability::OutOfStock
    pub availability: crate::model::product::Availability,

    /// The available quantity of the item.
    pub available_quantity: std::option::Option<wkt::Int32Value>,

    /// Fulfillment information, such as the store IDs for in-store pickup or
    /// region IDs for different shipping methods.
    ///
    /// All the elements must have distinct
    /// [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type].
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.FulfillmentInfo.type]: crate::model::FulfillmentInfo::type
    pub fulfillment_info: std::vec::Vec<crate::model::FulfillmentInfo>,

    /// Canonical URL directly linking to the product detail page.
    ///
    /// It is strongly recommended to provide a valid uri for the product,
    /// otherwise the service performance could be significantly degraded.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 5,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [link](https://support.google.com/merchants/answer/6324416). Schema.org
    /// property [Offer.url](https://schema.org/url).
    pub uri: std::string::String,

    /// Product images for the product. We highly recommend putting the main
    /// image first.
    ///
    /// A maximum of 300 images are allowed.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [image_link](https://support.google.com/merchants/answer/6324350).
    /// Schema.org property [Product.image](https://schema.org/image).
    pub images: std::vec::Vec<crate::model::Image>,

    /// The target group associated with a given audience (e.g. male, veterans,
    /// car owners, musicians, etc.) of the product.
    pub audience: std::option::Option<crate::model::Audience>,

    /// The color of the product.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [color](https://support.google.com/merchants/answer/6324487). Schema.org
    /// property [Product.color](https://schema.org/color).
    pub color_info: std::option::Option<crate::model::ColorInfo>,

    /// The size of the product. To represent different size systems or size types,
    /// consider using this format: [[[size_system:]size_type:]size_value].
    ///
    /// For example, in "US:MENS:M", "US" represents size system; "MENS" represents
    /// size type; "M" represents size value. In "GIRLS:27", size system is empty;
    /// "GIRLS" represents size type; "27" represents size value. In "32 inches",
    /// both size system and size type are empty, while size value is "32 inches".
    ///
    /// A maximum of 20 values are allowed per
    /// [Product][google.cloud.retail.v2.Product]. Each value must be a UTF-8
    /// encoded string with a length limit of 128 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [size](https://support.google.com/merchants/answer/6324492),
    /// [size_type](https://support.google.com/merchants/answer/6324497), and
    /// [size_system](https://support.google.com/merchants/answer/6324502).
    /// Schema.org property [Product.size](https://schema.org/size).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub sizes: std::vec::Vec<std::string::String>,

    /// The material of the product. For example, "leather", "wooden".
    ///
    /// A maximum of 20 values are allowed. Each value must be a UTF-8 encoded
    /// string with a length limit of 200 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [material](https://support.google.com/merchants/answer/6324410). Schema.org
    /// property [Product.material](https://schema.org/material).
    pub materials: std::vec::Vec<std::string::String>,

    /// The pattern or graphic print of the product. For example, "striped", "polka
    /// dot", "paisley".
    ///
    /// A maximum of 20 values are allowed per
    /// [Product][google.cloud.retail.v2.Product]. Each value must be a UTF-8
    /// encoded string with a length limit of 128 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [pattern](https://support.google.com/merchants/answer/6324483). Schema.org
    /// property [Product.pattern](https://schema.org/pattern).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub patterns: std::vec::Vec<std::string::String>,

    /// The condition of the product. Strongly encouraged to use the standard
    /// values: "new", "refurbished", "used".
    ///
    /// A maximum of 1 value is allowed per
    /// [Product][google.cloud.retail.v2.Product]. Each value must be a UTF-8
    /// encoded string with a length limit of 128 characters. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// Corresponding properties: Google Merchant Center property
    /// [condition](https://support.google.com/merchants/answer/6324469).
    /// Schema.org property
    /// [Offer.itemCondition](https://schema.org/itemCondition).
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub conditions: std::vec::Vec<std::string::String>,

    /// The promotions applied to the product. A maximum of 10 values are allowed
    /// per [Product][google.cloud.retail.v2.Product]. Only
    /// [Promotion.promotion_id][google.cloud.retail.v2.Promotion.promotion_id]
    /// will be used, other fields will be ignored if set.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Promotion.promotion_id]: crate::model::Promotion::promotion_id
    pub promotions: std::vec::Vec<crate::model::Promotion>,

    /// The timestamp when the product is published by the retailer for the first
    /// time, which indicates the freshness of the products. Note that this field
    /// is different from
    /// [available_time][google.cloud.retail.v2.Product.available_time], given it
    /// purely describes product freshness regardless of when it is available on
    /// search and recommendation.
    ///
    /// [google.cloud.retail.v2.Product.available_time]: crate::model::Product::available_time
    pub publish_time: std::option::Option<wkt::Timestamp>,

    /// Indicates which fields in the [Product][google.cloud.retail.v2.Product]s
    /// are returned in [SearchResponse][google.cloud.retail.v2.SearchResponse].
    ///
    /// Supported fields for all [type][google.cloud.retail.v2.Product.type]s:
    ///
    /// * [audience][google.cloud.retail.v2.Product.audience]
    /// * [availability][google.cloud.retail.v2.Product.availability]
    /// * [brands][google.cloud.retail.v2.Product.brands]
    /// * [color_info][google.cloud.retail.v2.Product.color_info]
    /// * [conditions][google.cloud.retail.v2.Product.conditions]
    /// * [gtin][google.cloud.retail.v2.Product.gtin]
    /// * [materials][google.cloud.retail.v2.Product.materials]
    /// * [name][google.cloud.retail.v2.Product.name]
    /// * [patterns][google.cloud.retail.v2.Product.patterns]
    /// * [price_info][google.cloud.retail.v2.Product.price_info]
    /// * [rating][google.cloud.retail.v2.Product.rating]
    /// * [sizes][google.cloud.retail.v2.Product.sizes]
    /// * [title][google.cloud.retail.v2.Product.title]
    /// * [uri][google.cloud.retail.v2.Product.uri]
    ///
    /// Supported fields only for
    /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] and
    /// [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]:
    ///
    /// * [categories][google.cloud.retail.v2.Product.categories]
    /// * [description][google.cloud.retail.v2.Product.description]
    /// * [images][google.cloud.retail.v2.Product.images]
    ///
    /// Supported fields only for
    /// [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]:
    ///
    /// * Only the first image in [images][google.cloud.retail.v2.Product.images]
    ///
    /// To mark [attributes][google.cloud.retail.v2.Product.attributes] as
    /// retrievable, include paths of the form "attributes.key" where "key" is the
    /// key of a custom attribute, as specified in
    /// [attributes][google.cloud.retail.v2.Product.attributes].
    ///
    /// For [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] and
    /// [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], the
    /// following fields are always returned in
    /// [SearchResponse][google.cloud.retail.v2.SearchResponse] by default:
    ///
    /// * [name][google.cloud.retail.v2.Product.name]
    ///
    /// For [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT], the
    /// following fields are always returned in by default:
    ///
    /// * [name][google.cloud.retail.v2.Product.name]
    /// * [color_info][google.cloud.retail.v2.Product.color_info]
    ///
    /// Note: Returning more fields in
    /// [SearchResponse][google.cloud.retail.v2.SearchResponse] can increase
    /// response payload size and serving latency.
    ///
    /// This field is deprecated. Use the retrievable site-wide control instead.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.Product.attributes]: crate::model::Product::attributes
    /// [google.cloud.retail.v2.Product.audience]: crate::model::Product::audience
    /// [google.cloud.retail.v2.Product.availability]: crate::model::Product::availability
    /// [google.cloud.retail.v2.Product.brands]: crate::model::Product::brands
    /// [google.cloud.retail.v2.Product.categories]: crate::model::Product::categories
    /// [google.cloud.retail.v2.Product.color_info]: crate::model::Product::color_info
    /// [google.cloud.retail.v2.Product.conditions]: crate::model::Product::conditions
    /// [google.cloud.retail.v2.Product.description]: crate::model::Product::description
    /// [google.cloud.retail.v2.Product.gtin]: crate::model::Product::gtin
    /// [google.cloud.retail.v2.Product.images]: crate::model::Product::images
    /// [google.cloud.retail.v2.Product.materials]: crate::model::Product::materials
    /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
    /// [google.cloud.retail.v2.Product.patterns]: crate::model::Product::patterns
    /// [google.cloud.retail.v2.Product.price_info]: crate::model::Product::price_info
    /// [google.cloud.retail.v2.Product.rating]: crate::model::Product::rating
    /// [google.cloud.retail.v2.Product.sizes]: crate::model::Product::sizes
    /// [google.cloud.retail.v2.Product.title]: crate::model::Product::title
    /// [google.cloud.retail.v2.Product.type]: crate::model::Product::type
    /// [google.cloud.retail.v2.Product.uri]: crate::model::Product::uri
    /// [google.cloud.retail.v2.SearchResponse]: crate::model::SearchResponse
    #[deprecated]
    pub retrievable_fields: std::option::Option<wkt::FieldMask>,

    /// Output only. Product variants grouped together on primary product which
    /// share similar product attributes. It's automatically grouped by
    /// [primary_product_id][google.cloud.retail.v2.Product.primary_product_id] for
    /// all the product variants. Only populated for
    /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product]s.
    ///
    /// Note: This field is OUTPUT_ONLY for
    /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct].
    /// Do not set this field in API requests.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.primary_product_id]: crate::model::Product::primary_product_id
    /// [google.cloud.retail.v2.ProductService.GetProduct]: crate::client::ProductService::get_product
    pub variants: std::vec::Vec<crate::model::Product>,

    /// Output only. A list of local inventories specific to different places.
    ///
    /// This field can be managed by
    /// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
    /// and
    /// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
    /// APIs if fine-grained, high-volume updates are necessary.
    ///
    /// [google.cloud.retail.v2.ProductService.AddLocalInventories]: crate::client::ProductService::add_local_inventories
    /// [google.cloud.retail.v2.ProductService.RemoveLocalInventories]: crate::client::ProductService::remove_local_inventories
    pub local_inventories: std::vec::Vec<crate::model::LocalInventory>,

    pub expiration: std::option::Option<crate::model::product::Expiration>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Product {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::Product::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [id][crate::model::Product::id].
    pub fn set_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.id = v.into();
        self
    }

    /// Sets the value of [r#type][crate::model::Product::type].
    pub fn set_type<T: std::convert::Into<crate::model::product::Type>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [primary_product_id][crate::model::Product::primary_product_id].
    pub fn set_primary_product_id<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.primary_product_id = v.into();
        self
    }

    /// Sets the value of [collection_member_ids][crate::model::Product::collection_member_ids].
    pub fn set_collection_member_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.collection_member_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [gtin][crate::model::Product::gtin].
    pub fn set_gtin<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.gtin = v.into();
        self
    }

    /// Sets the value of [categories][crate::model::Product::categories].
    pub fn set_categories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.categories = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [title][crate::model::Product::title].
    pub fn set_title<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.title = v.into();
        self
    }

    /// Sets the value of [brands][crate::model::Product::brands].
    pub fn set_brands<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.brands = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [description][crate::model::Product::description].
    pub fn set_description<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.description = v.into();
        self
    }

    /// Sets the value of [language_code][crate::model::Product::language_code].
    pub fn set_language_code<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.language_code = v.into();
        self
    }

    /// Sets the value of [attributes][crate::model::Product::attributes].
    pub fn set_attributes<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::CustomAttribute>,
    {
        use std::iter::Iterator;
        self.attributes = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [tags][crate::model::Product::tags].
    pub fn set_tags<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.tags = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [price_info][crate::model::Product::price_info].
    pub fn set_price_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::PriceInfo>,
    {
        self.price_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [price_info][crate::model::Product::price_info].
    pub fn set_or_clear_price_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::PriceInfo>,
    {
        self.price_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [rating][crate::model::Product::rating].
    pub fn set_rating<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Rating>,
    {
        self.rating = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [rating][crate::model::Product::rating].
    pub fn set_or_clear_rating<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Rating>,
    {
        self.rating = v.map(|x| x.into());
        self
    }

    /// Sets the value of [available_time][crate::model::Product::available_time].
    pub fn set_available_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.available_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [available_time][crate::model::Product::available_time].
    pub fn set_or_clear_available_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.available_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [availability][crate::model::Product::availability].
    pub fn set_availability<T: std::convert::Into<crate::model::product::Availability>>(
        mut self,
        v: T,
    ) -> Self {
        self.availability = v.into();
        self
    }

    /// Sets the value of [available_quantity][crate::model::Product::available_quantity].
    pub fn set_available_quantity<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.available_quantity = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [available_quantity][crate::model::Product::available_quantity].
    pub fn set_or_clear_available_quantity<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.available_quantity = v.map(|x| x.into());
        self
    }

    /// Sets the value of [fulfillment_info][crate::model::Product::fulfillment_info].
    pub fn set_fulfillment_info<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::FulfillmentInfo>,
    {
        use std::iter::Iterator;
        self.fulfillment_info = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [uri][crate::model::Product::uri].
    pub fn set_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.uri = v.into();
        self
    }

    /// Sets the value of [images][crate::model::Product::images].
    pub fn set_images<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Image>,
    {
        use std::iter::Iterator;
        self.images = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [audience][crate::model::Product::audience].
    pub fn set_audience<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Audience>,
    {
        self.audience = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [audience][crate::model::Product::audience].
    pub fn set_or_clear_audience<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Audience>,
    {
        self.audience = v.map(|x| x.into());
        self
    }

    /// Sets the value of [color_info][crate::model::Product::color_info].
    pub fn set_color_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ColorInfo>,
    {
        self.color_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [color_info][crate::model::Product::color_info].
    pub fn set_or_clear_color_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ColorInfo>,
    {
        self.color_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [sizes][crate::model::Product::sizes].
    pub fn set_sizes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.sizes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [materials][crate::model::Product::materials].
    pub fn set_materials<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.materials = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [patterns][crate::model::Product::patterns].
    pub fn set_patterns<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.patterns = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [conditions][crate::model::Product::conditions].
    pub fn set_conditions<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.conditions = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [promotions][crate::model::Product::promotions].
    pub fn set_promotions<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Promotion>,
    {
        use std::iter::Iterator;
        self.promotions = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [publish_time][crate::model::Product::publish_time].
    pub fn set_publish_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.publish_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [publish_time][crate::model::Product::publish_time].
    pub fn set_or_clear_publish_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.publish_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [retrievable_fields][crate::model::Product::retrievable_fields].
    #[deprecated]
    pub fn set_retrievable_fields<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.retrievable_fields = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [retrievable_fields][crate::model::Product::retrievable_fields].
    #[deprecated]
    pub fn set_or_clear_retrievable_fields<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.retrievable_fields = v.map(|x| x.into());
        self
    }

    /// Sets the value of [variants][crate::model::Product::variants].
    pub fn set_variants<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Product>,
    {
        use std::iter::Iterator;
        self.variants = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [local_inventories][crate::model::Product::local_inventories].
    pub fn set_local_inventories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::LocalInventory>,
    {
        use std::iter::Iterator;
        self.local_inventories = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [expiration][crate::model::Product::expiration].
    ///
    /// Note that all the setters affecting `expiration` are mutually
    /// exclusive.
    pub fn set_expiration<
        T: std::convert::Into<std::option::Option<crate::model::product::Expiration>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.expiration = v.into();
        self
    }

    /// The value of [expiration][crate::model::Product::expiration]
    /// if it holds a `ExpireTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn expire_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.expiration.as_ref().and_then(|v| match v {
            crate::model::product::Expiration::ExpireTime(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [expiration][crate::model::Product::expiration]
    /// to hold a `ExpireTime`.
    ///
    /// Note that all the setters affecting `expiration` are
    /// mutually exclusive.
    pub fn set_expire_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.expiration =
            std::option::Option::Some(crate::model::product::Expiration::ExpireTime(v.into()));
        self
    }

    /// The value of [expiration][crate::model::Product::expiration]
    /// if it holds a `Ttl`, `None` if the field is not set or
    /// holds a different branch.
    pub fn ttl(&self) -> std::option::Option<&std::boxed::Box<wkt::Duration>> {
        #[allow(unreachable_patterns)]
        self.expiration.as_ref().and_then(|v| match v {
            crate::model::product::Expiration::Ttl(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [expiration][crate::model::Product::expiration]
    /// to hold a `Ttl`.
    ///
    /// Note that all the setters affecting `expiration` are
    /// mutually exclusive.
    pub fn set_ttl<T: std::convert::Into<std::boxed::Box<wkt::Duration>>>(mut self, v: T) -> Self {
        self.expiration =
            std::option::Option::Some(crate::model::product::Expiration::Ttl(v.into()));
        self
    }
}

impl wkt::message::Message for Product {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Product"
    }
}

/// Defines additional types related to [Product].
pub mod product {
    #[allow(unused_imports)]
    use super::*;

    /// The type of this product.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Type {
        /// Default value. Default to
        /// [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type]
        /// if unset.
        ///
        /// [google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type]: crate::model::ProductLevelConfig::ingestion_product_type
        Unspecified,
        /// The primary type.
        ///
        /// As the primary unit for predicting, indexing and search serving, a
        /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
        /// [Product][google.cloud.retail.v2.Product] is grouped with multiple
        /// [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product]s.
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        Primary,
        /// The variant type.
        ///
        /// [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product]s usually share some common
        /// attributes on the same
        /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
        /// [Product][google.cloud.retail.v2.Product]s, but they have variant
        /// attributes like different colors, sizes and prices, etc.
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        Variant,
        /// The collection type. Collection products are bundled
        /// [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
        /// [Product][google.cloud.retail.v2.Product]s or
        /// [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product]s that are sold together, such
        /// as a jewelry set with necklaces, earrings and rings, etc.
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        Collection,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [Type::value] or
        /// [Type::name].
        UnknownValue(r#type::UnknownValue),
    }

    #[doc(hidden)]
    pub mod r#type {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl Type {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Primary => std::option::Option::Some(1),
                Self::Variant => std::option::Option::Some(2),
                Self::Collection => std::option::Option::Some(3),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("TYPE_UNSPECIFIED"),
                Self::Primary => std::option::Option::Some("PRIMARY"),
                Self::Variant => std::option::Option::Some("VARIANT"),
                Self::Collection => std::option::Option::Some("COLLECTION"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for Type {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for Type {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for Type {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Primary,
                2 => Self::Variant,
                3 => Self::Collection,
                _ => Self::UnknownValue(r#type::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for Type {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "TYPE_UNSPECIFIED" => Self::Unspecified,
                "PRIMARY" => Self::Primary,
                "VARIANT" => Self::Variant,
                "COLLECTION" => Self::Collection,
                _ => Self::UnknownValue(r#type::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for Type {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Primary => serializer.serialize_i32(1),
                Self::Variant => serializer.serialize_i32(2),
                Self::Collection => serializer.serialize_i32(3),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for Type {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<Type>::new(
                ".google.cloud.retail.v2.Product.Type",
            ))
        }
    }

    /// Product availability. If this field is unspecified, the product is
    /// assumed to be in stock.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Availability {
        /// Default product availability. Default to
        /// [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK]
        /// if unset.
        ///
        /// [google.cloud.retail.v2.Product.Availability.IN_STOCK]: crate::model::product::Availability::InStock
        Unspecified,
        /// Product in stock.
        InStock,
        /// Product out of stock.
        OutOfStock,
        /// Product that is in pre-order state.
        Preorder,
        /// Product that is back-ordered (i.e. temporarily out of stock).
        Backorder,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [Availability::value] or
        /// [Availability::name].
        UnknownValue(availability::UnknownValue),
    }

    #[doc(hidden)]
    pub mod availability {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl Availability {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::InStock => std::option::Option::Some(1),
                Self::OutOfStock => std::option::Option::Some(2),
                Self::Preorder => std::option::Option::Some(3),
                Self::Backorder => std::option::Option::Some(4),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("AVAILABILITY_UNSPECIFIED"),
                Self::InStock => std::option::Option::Some("IN_STOCK"),
                Self::OutOfStock => std::option::Option::Some("OUT_OF_STOCK"),
                Self::Preorder => std::option::Option::Some("PREORDER"),
                Self::Backorder => std::option::Option::Some("BACKORDER"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for Availability {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for Availability {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for Availability {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::InStock,
                2 => Self::OutOfStock,
                3 => Self::Preorder,
                4 => Self::Backorder,
                _ => Self::UnknownValue(availability::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for Availability {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "AVAILABILITY_UNSPECIFIED" => Self::Unspecified,
                "IN_STOCK" => Self::InStock,
                "OUT_OF_STOCK" => Self::OutOfStock,
                "PREORDER" => Self::Preorder,
                "BACKORDER" => Self::Backorder,
                _ => Self::UnknownValue(availability::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for Availability {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::InStock => serializer.serialize_i32(1),
                Self::OutOfStock => serializer.serialize_i32(2),
                Self::Preorder => serializer.serialize_i32(3),
                Self::Backorder => serializer.serialize_i32(4),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for Availability {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<Availability>::new(
                ".google.cloud.retail.v2.Product.Availability",
            ))
        }
    }

    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Expiration {
        /// Note that this field is applied in the following ways:
        ///
        /// * If the [Product][google.cloud.retail.v2.Product] is already expired
        ///   when it is uploaded, this product
        ///   is not indexed for search.
        ///
        /// * If the [Product][google.cloud.retail.v2.Product] is not expired when it
        ///   is uploaded, only the
        ///   [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]'s and
        ///   [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]'s
        ///   expireTime is respected, and
        ///   [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]'s
        ///   expireTime is not used.
        ///
        ///
        /// In general, we suggest the users to delete the stale
        /// products explicitly, instead of using this field to determine staleness.
        ///
        /// [expire_time][google.cloud.retail.v2.Product.expire_time] must be later
        /// than [available_time][google.cloud.retail.v2.Product.available_time] and
        /// [publish_time][google.cloud.retail.v2.Product.publish_time], otherwise an
        /// INVALID_ARGUMENT error is thrown.
        ///
        /// Corresponding properties: Google Merchant Center property
        /// [expiration_date](https://support.google.com/merchants/answer/6324499).
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
        /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        /// [google.cloud.retail.v2.Product.available_time]: crate::model::Product::available_time
        /// [google.cloud.retail.v2.Product.expire_time]: crate::model::Product::expiration
        /// [google.cloud.retail.v2.Product.publish_time]: crate::model::Product::publish_time
        ExpireTime(std::boxed::Box<wkt::Timestamp>),
        /// Input only. The TTL (time to live) of the product. Note that this is only
        /// applicable to [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
        /// and [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION],
        /// and ignored for
        /// [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]. In general,
        /// we suggest the users to delete the stale products explicitly, instead of
        /// using this field to determine staleness.
        ///
        /// If it is set, it must be a non-negative value, and
        /// [expire_time][google.cloud.retail.v2.Product.expire_time] is set as
        /// current timestamp plus [ttl][google.cloud.retail.v2.Product.ttl]. The
        /// derived [expire_time][google.cloud.retail.v2.Product.expire_time] is
        /// returned in the output and [ttl][google.cloud.retail.v2.Product.ttl] is
        /// left blank when retrieving the [Product][google.cloud.retail.v2.Product].
        ///
        /// If it is set, the product is not available for
        /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] after
        /// current timestamp plus [ttl][google.cloud.retail.v2.Product.ttl].
        /// However, the product can still be retrieved by
        /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
        /// and
        /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
        /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        /// [google.cloud.retail.v2.Product.expire_time]: crate::model::Product::expiration
        /// [google.cloud.retail.v2.Product.ttl]: crate::model::Product::expiration
        /// [google.cloud.retail.v2.ProductService.GetProduct]: crate::client::ProductService::get_product
        /// [google.cloud.retail.v2.ProductService.ListProducts]: crate::client::ProductService::list_products
        /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
        Ttl(std::boxed::Box<wkt::Duration>),
    }
}

/// Request message for
/// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
/// method.
///
/// [google.cloud.retail.v2.ProductService.CreateProduct]: crate::client::ProductService::create_product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CreateProductRequest {
    /// Required. The parent catalog resource name, such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch`.
    pub parent: std::string::String,

    /// Required. The [Product][google.cloud.retail.v2.Product] to create.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub product: std::option::Option<crate::model::Product>,

    /// Required. The ID to use for the [Product][google.cloud.retail.v2.Product],
    /// which will become the final component of the
    /// [Product.name][google.cloud.retail.v2.Product.name].
    ///
    /// If the caller does not have permission to create the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// This field must be unique among all
    /// [Product][google.cloud.retail.v2.Product]s with the same
    /// [parent][google.cloud.retail.v2.CreateProductRequest.parent]. Otherwise, an
    /// ALREADY_EXISTS error is returned.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.CreateProductRequest.parent]: crate::model::CreateProductRequest::parent
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
    pub product_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CreateProductRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::CreateProductRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [product][crate::model::CreateProductRequest::product].
    pub fn set_product<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.product = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [product][crate::model::CreateProductRequest::product].
    pub fn set_or_clear_product<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.product = v.map(|x| x.into());
        self
    }

    /// Sets the value of [product_id][crate::model::CreateProductRequest::product_id].
    pub fn set_product_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.product_id = v.into();
        self
    }
}

impl wkt::message::Message for CreateProductRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CreateProductRequest"
    }
}

/// Request message for
/// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
/// method.
///
/// [google.cloud.retail.v2.ProductService.GetProduct]: crate::client::ProductService::get_product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetProductRequest {
    /// Required. Full resource name of [Product][google.cloud.retail.v2.Product],
    /// such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
    ///
    /// If the caller does not have permission to access the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// If the requested [Product][google.cloud.retail.v2.Product] does not exist,
    /// a NOT_FOUND error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetProductRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetProductRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for GetProductRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetProductRequest"
    }
}

/// Request message for
/// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
/// method.
///
/// [google.cloud.retail.v2.ProductService.UpdateProduct]: crate::client::ProductService::update_product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateProductRequest {
    /// Required. The product to update/create.
    ///
    /// If the caller does not have permission to update the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// If the [Product][google.cloud.retail.v2.Product] to update does not exist
    /// and
    /// [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing]
    /// is not set, a NOT_FOUND error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.UpdateProductRequest.allow_missing]: crate::model::UpdateProductRequest::allow_missing
    pub product: std::option::Option<crate::model::Product>,

    /// Indicates which fields in the provided
    /// [Product][google.cloud.retail.v2.Product] to update. The immutable and
    /// output only fields are NOT supported. If not set, all supported fields (the
    /// fields that are neither immutable nor output only) are updated.
    ///
    /// If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
    /// is returned.
    ///
    /// The attribute key can be updated by setting the mask path as
    /// "attributes.${key_name}". If a key name is present in the mask but not in
    /// the patching product from the request, this key will be deleted after the
    /// update.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub update_mask: std::option::Option<wkt::FieldMask>,

    /// If set to true, and the [Product][google.cloud.retail.v2.Product] is not
    /// found, a new [Product][google.cloud.retail.v2.Product] will be created. In
    /// this situation, `update_mask` is ignored.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub allow_missing: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateProductRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [product][crate::model::UpdateProductRequest::product].
    pub fn set_product<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.product = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [product][crate::model::UpdateProductRequest::product].
    pub fn set_or_clear_product<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.product = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateProductRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateProductRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_missing][crate::model::UpdateProductRequest::allow_missing].
    pub fn set_allow_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allow_missing = v.into();
        self
    }
}

impl wkt::message::Message for UpdateProductRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateProductRequest"
    }
}

/// Request message for
/// [ProductService.DeleteProduct][google.cloud.retail.v2.ProductService.DeleteProduct]
/// method.
///
/// [google.cloud.retail.v2.ProductService.DeleteProduct]: crate::client::ProductService::delete_product
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DeleteProductRequest {
    /// Required. Full resource name of [Product][google.cloud.retail.v2.Product],
    /// such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
    ///
    /// If the caller does not have permission to delete the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// If the [Product][google.cloud.retail.v2.Product] to delete does not exist,
    /// a NOT_FOUND error is returned.
    ///
    /// The [Product][google.cloud.retail.v2.Product] to delete can neither be a
    /// [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]
    /// [Product][google.cloud.retail.v2.Product] member nor a
    /// [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product] with more than one
    /// [variants][google.cloud.retail.v2.Product.Type.VARIANT]. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// All inventory information for the named
    /// [Product][google.cloud.retail.v2.Product] will be deleted.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DeleteProductRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::DeleteProductRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for DeleteProductRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.DeleteProductRequest"
    }
}

/// Request message for
/// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]
/// method.
///
/// [google.cloud.retail.v2.ProductService.ListProducts]: crate::client::ProductService::list_products
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListProductsRequest {
    /// Required. The parent branch resource name, such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/0`. Use
    /// `default_branch` as the branch ID, to list products under the default
    /// branch.
    ///
    /// If the caller does not have permission to list
    /// [Product][google.cloud.retail.v2.Product]s under this branch, regardless of
    /// whether or not this branch exists, a PERMISSION_DENIED error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub parent: std::string::String,

    /// Maximum number of [Product][google.cloud.retail.v2.Product]s to return. If
    /// unspecified, defaults to 100. The maximum allowed value is 1000. Values
    /// above 1000 will be coerced to 1000.
    ///
    /// If this field is negative, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub page_size: i32,

    /// A page token
    /// [ListProductsResponse.next_page_token][google.cloud.retail.v2.ListProductsResponse.next_page_token],
    /// received from a previous
    /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]
    /// call. Provide this to retrieve the subsequent page.
    ///
    /// When paginating, all other parameters provided to
    /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]
    /// must match the call that provided the page token. Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.ListProductsResponse.next_page_token]: crate::model::ListProductsResponse::next_page_token
    /// [google.cloud.retail.v2.ProductService.ListProducts]: crate::client::ProductService::list_products
    pub page_token: std::string::String,

    /// A filter to apply on the list results. Supported features:
    ///
    /// * List all the products under the parent branch if
    ///   [filter][google.cloud.retail.v2.ListProductsRequest.filter] is unset.
    /// * List [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]
    ///   [Product][google.cloud.retail.v2.Product]s sharing the same
    ///   [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    ///   [Product][google.cloud.retail.v2.Product]. For example:
    ///   `primary_product_id = "some_product_id"`
    /// * List [Product][google.cloud.retail.v2.Product]s bundled in a
    ///   [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]
    ///   [Product][google.cloud.retail.v2.Product].
    ///   For example:
    ///   `collection_product_id = "some_product_id"`
    /// * List [Product][google.cloud.retail.v2.Product]s with a partibular type.
    ///   For example:
    ///   `type = "PRIMARY"`
    ///   `type = "VARIANT"`
    ///   `type = "COLLECTION"`
    ///
    /// If the field is unrecognizable, an INVALID_ARGUMENT error is returned.
    ///
    /// If the specified
    /// [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
    /// [Product][google.cloud.retail.v2.Product] or
    /// [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]
    /// [Product][google.cloud.retail.v2.Product] does not exist, a NOT_FOUND error
    /// is returned.
    ///
    /// [google.cloud.retail.v2.ListProductsRequest.filter]: crate::model::ListProductsRequest::filter
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.COLLECTION]: crate::model::product::Type::Collection
    /// [google.cloud.retail.v2.Product.Type.PRIMARY]: crate::model::product::Type::Primary
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    pub filter: std::string::String,

    /// The fields of [Product][google.cloud.retail.v2.Product] to return in the
    /// responses. If not set or empty, the following fields are returned:
    ///
    /// * [Product.name][google.cloud.retail.v2.Product.name]
    /// * [Product.id][google.cloud.retail.v2.Product.id]
    /// * [Product.title][google.cloud.retail.v2.Product.title]
    /// * [Product.uri][google.cloud.retail.v2.Product.uri]
    /// * [Product.images][google.cloud.retail.v2.Product.images]
    /// * [Product.price_info][google.cloud.retail.v2.Product.price_info]
    /// * [Product.brands][google.cloud.retail.v2.Product.brands]
    ///
    /// If "*" is provided, all fields are returned.
    /// [Product.name][google.cloud.retail.v2.Product.name] is always returned no
    /// matter what mask is set.
    ///
    /// If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
    /// is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.brands]: crate::model::Product::brands
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    /// [google.cloud.retail.v2.Product.images]: crate::model::Product::images
    /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
    /// [google.cloud.retail.v2.Product.price_info]: crate::model::Product::price_info
    /// [google.cloud.retail.v2.Product.title]: crate::model::Product::title
    /// [google.cloud.retail.v2.Product.uri]: crate::model::Product::uri
    pub read_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListProductsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListProductsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListProductsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListProductsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::ListProductsRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }

    /// Sets the value of [read_mask][crate::model::ListProductsRequest::read_mask].
    pub fn set_read_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.read_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_mask][crate::model::ListProductsRequest::read_mask].
    pub fn set_or_clear_read_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.read_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ListProductsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListProductsRequest"
    }
}

/// Response message for
/// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]
/// method.
///
/// [google.cloud.retail.v2.ProductService.ListProducts]: crate::client::ProductService::list_products
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListProductsResponse {
    /// The [Product][google.cloud.retail.v2.Product]s.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub products: std::vec::Vec<crate::model::Product>,

    /// A token that can be sent as
    /// [ListProductsRequest.page_token][google.cloud.retail.v2.ListProductsRequest.page_token]
    /// to retrieve the next page. If this field is omitted, there are no
    /// subsequent pages.
    ///
    /// [google.cloud.retail.v2.ListProductsRequest.page_token]: crate::model::ListProductsRequest::page_token
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListProductsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [products][crate::model::ListProductsResponse::products].
    pub fn set_products<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Product>,
    {
        use std::iter::Iterator;
        self.products = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListProductsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListProductsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListProductsResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for ListProductsResponse {
    type PageItem = crate::model::Product;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.products
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// Request message for
/// [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory]
/// method.
///
/// [google.cloud.retail.v2.ProductService.SetInventory]: crate::client::ProductService::set_inventory
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SetInventoryRequest {
    /// Required. The inventory information to update. The allowable fields to
    /// update are:
    ///
    /// * [Product.price_info][google.cloud.retail.v2.Product.price_info]
    /// * [Product.availability][google.cloud.retail.v2.Product.availability]
    /// * [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity]
    /// * [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info]
    ///   The updated inventory fields must be specified in
    ///   [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask].
    ///
    /// If
    /// [SetInventoryRequest.inventory.name][google.cloud.retail.v2.Product.name]
    /// is empty or invalid, an INVALID_ARGUMENT error is returned.
    ///
    /// If the caller does not have permission to update the
    /// [Product][google.cloud.retail.v2.Product] named in
    /// [Product.name][google.cloud.retail.v2.Product.name], regardless of whether
    /// or not it exists, a PERMISSION_DENIED error is returned.
    ///
    /// If the [Product][google.cloud.retail.v2.Product] to update does not have
    /// existing inventory information, the provided inventory information will be
    /// inserted.
    ///
    /// If the [Product][google.cloud.retail.v2.Product] to update has existing
    /// inventory information, the provided inventory information will be merged
    /// while respecting the last update time for each inventory field, using the
    /// provided or default value for
    /// [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time].
    ///
    /// The caller can replace place IDs for a subset of fulfillment types in the
    /// following ways:
    ///
    /// * Adds "fulfillment_info" in
    ///   [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]
    /// * Specifies only the desired fulfillment types and corresponding place IDs
    ///   to update in
    ///   [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info]
    ///
    /// The caller can clear all place IDs from a subset of fulfillment types in
    /// the following ways:
    ///
    /// * Adds "fulfillment_info" in
    ///   [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]
    /// * Specifies only the desired fulfillment types to clear in
    ///   [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info]
    /// * Checks that only the desired fulfillment info types have empty
    ///   [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///
    /// The last update time is recorded for the following inventory fields:
    ///
    /// * [Product.price_info][google.cloud.retail.v2.Product.price_info]
    /// * [Product.availability][google.cloud.retail.v2.Product.availability]
    /// * [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity]
    /// * [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info]
    ///
    /// If a full overwrite of inventory information while ignoring timestamps is
    /// needed,
    /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
    /// should be invoked instead.
    ///
    /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: crate::model::FulfillmentInfo::place_ids
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.availability]: crate::model::Product::availability
    /// [google.cloud.retail.v2.Product.available_quantity]: crate::model::Product::available_quantity
    /// [google.cloud.retail.v2.Product.fulfillment_info]: crate::model::Product::fulfillment_info
    /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
    /// [google.cloud.retail.v2.Product.price_info]: crate::model::Product::price_info
    /// [google.cloud.retail.v2.ProductService.UpdateProduct]: crate::client::ProductService::update_product
    /// [google.cloud.retail.v2.SetInventoryRequest.set_mask]: crate::model::SetInventoryRequest::set_mask
    /// [google.cloud.retail.v2.SetInventoryRequest.set_time]: crate::model::SetInventoryRequest::set_time
    pub inventory: std::option::Option<crate::model::Product>,

    /// Indicates which inventory fields in the provided
    /// [Product][google.cloud.retail.v2.Product] to update.
    ///
    /// At least one field must be provided.
    ///
    /// If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
    /// is returned and the entire update will be ignored.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub set_mask: std::option::Option<wkt::FieldMask>,

    /// The time when the request is issued, used to prevent
    /// out-of-order updates on inventory fields with the last update time
    /// recorded. If not provided, the internal system time will be used.
    pub set_time: std::option::Option<wkt::Timestamp>,

    /// If set to true, and the [Product][google.cloud.retail.v2.Product] with name
    /// [Product.name][google.cloud.retail.v2.Product.name] is not found, the
    /// inventory update will still be processed and retained for at most 1 day
    /// until the [Product][google.cloud.retail.v2.Product] is created. If set to
    /// false, a NOT_FOUND error is returned if the
    /// [Product][google.cloud.retail.v2.Product] is not found.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
    pub allow_missing: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SetInventoryRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [inventory][crate::model::SetInventoryRequest::inventory].
    pub fn set_inventory<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.inventory = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [inventory][crate::model::SetInventoryRequest::inventory].
    pub fn set_or_clear_inventory<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.inventory = v.map(|x| x.into());
        self
    }

    /// Sets the value of [set_mask][crate::model::SetInventoryRequest::set_mask].
    pub fn set_set_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.set_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [set_mask][crate::model::SetInventoryRequest::set_mask].
    pub fn set_or_clear_set_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.set_mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [set_time][crate::model::SetInventoryRequest::set_time].
    pub fn set_set_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.set_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [set_time][crate::model::SetInventoryRequest::set_time].
    pub fn set_or_clear_set_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.set_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_missing][crate::model::SetInventoryRequest::allow_missing].
    pub fn set_allow_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allow_missing = v.into();
        self
    }
}

impl wkt::message::Message for SetInventoryRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SetInventoryRequest"
    }
}

/// Metadata related to the progress of the SetInventory operation.
/// Currently empty because there is no meaningful metadata populated from the
/// [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory]
/// method.
///
/// [google.cloud.retail.v2.ProductService.SetInventory]: crate::client::ProductService::set_inventory
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SetInventoryMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SetInventoryMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for SetInventoryMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SetInventoryMetadata"
    }
}

/// Response of the SetInventoryRequest.  Currently empty because
/// there is no meaningful response populated from the
/// [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory]
/// method.
///
/// [google.cloud.retail.v2.ProductService.SetInventory]: crate::client::ProductService::set_inventory
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SetInventoryResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SetInventoryResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for SetInventoryResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SetInventoryResponse"
    }
}

/// Request message for
/// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]
/// method.
///
/// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: crate::client::ProductService::add_fulfillment_places
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddFulfillmentPlacesRequest {
    /// Required. Full resource name of [Product][google.cloud.retail.v2.Product],
    /// such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
    ///
    /// If the caller does not have permission to access the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub product: std::string::String,

    /// Required. The fulfillment type, including commonly used types (such as
    /// pickup in store and same day delivery), and custom types.
    ///
    /// Supported values:
    ///
    /// * "pickup-in-store"
    /// * "ship-to-store"
    /// * "same-day-delivery"
    /// * "next-day-delivery"
    /// * "custom-type-1"
    /// * "custom-type-2"
    /// * "custom-type-3"
    /// * "custom-type-4"
    /// * "custom-type-5"
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// This field directly corresponds to
    /// [Product.fulfillment_info.type][google.cloud.retail.v2.FulfillmentInfo.type].
    ///
    /// [google.cloud.retail.v2.FulfillmentInfo.type]: crate::model::FulfillmentInfo::type
    pub r#type: std::string::String,

    /// Required. The IDs for this
    /// [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type], such as
    /// the store IDs for "pickup-in-store" or the region IDs for
    /// "same-day-delivery" to be added for this
    /// [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type]. Duplicate
    /// IDs will be automatically ignored.
    ///
    /// At least 1 value is required, and a maximum of 2000 values are allowed.
    /// Each value must be a string with a length limit of 10 characters, matching
    /// the pattern `[a-zA-Z0-9_-]+`, such as "store1" or "REGION-2". Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// If the total number of place IDs exceeds 2000 for this
    /// [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type] after
    /// adding, then the update will be rejected.
    ///
    /// [google.cloud.retail.v2.AddFulfillmentPlacesRequest.type]: crate::model::AddFulfillmentPlacesRequest::type
    pub place_ids: std::vec::Vec<std::string::String>,

    /// The time when the fulfillment updates are issued, used to prevent
    /// out-of-order updates on fulfillment information. If not provided, the
    /// internal system time will be used.
    pub add_time: std::option::Option<wkt::Timestamp>,

    /// If set to true, and the [Product][google.cloud.retail.v2.Product] is not
    /// found, the fulfillment information will still be processed and retained for
    /// at most 1 day and processed once the
    /// [Product][google.cloud.retail.v2.Product] is created. If set to false, a
    /// NOT_FOUND error is returned if the
    /// [Product][google.cloud.retail.v2.Product] is not found.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub allow_missing: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddFulfillmentPlacesRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [product][crate::model::AddFulfillmentPlacesRequest::product].
    pub fn set_product<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.product = v.into();
        self
    }

    /// Sets the value of [r#type][crate::model::AddFulfillmentPlacesRequest::type].
    pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [place_ids][crate::model::AddFulfillmentPlacesRequest::place_ids].
    pub fn set_place_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.place_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [add_time][crate::model::AddFulfillmentPlacesRequest::add_time].
    pub fn set_add_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.add_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [add_time][crate::model::AddFulfillmentPlacesRequest::add_time].
    pub fn set_or_clear_add_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.add_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_missing][crate::model::AddFulfillmentPlacesRequest::allow_missing].
    pub fn set_allow_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allow_missing = v.into();
        self
    }
}

impl wkt::message::Message for AddFulfillmentPlacesRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddFulfillmentPlacesRequest"
    }
}

/// Metadata related to the progress of the AddFulfillmentPlaces operation.
/// Currently empty because there is no meaningful metadata populated from the
/// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]
/// method.
///
/// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: crate::client::ProductService::add_fulfillment_places
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddFulfillmentPlacesMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddFulfillmentPlacesMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for AddFulfillmentPlacesMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddFulfillmentPlacesMetadata"
    }
}

/// Response of the AddFulfillmentPlacesRequest.  Currently empty because
/// there is no meaningful response populated from the
/// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]
/// method.
///
/// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: crate::client::ProductService::add_fulfillment_places
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddFulfillmentPlacesResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddFulfillmentPlacesResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for AddFulfillmentPlacesResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddFulfillmentPlacesResponse"
    }
}

/// Request message for
/// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
/// method.
///
/// [google.cloud.retail.v2.ProductService.AddLocalInventories]: crate::client::ProductService::add_local_inventories
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddLocalInventoriesRequest {
    /// Required. Full resource name of [Product][google.cloud.retail.v2.Product],
    /// such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
    ///
    /// If the caller does not have permission to access the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub product: std::string::String,

    /// Required. A list of inventory information at difference places. Each place
    /// is identified by its place ID. At most 3000 inventories are allowed per
    /// request.
    pub local_inventories: std::vec::Vec<crate::model::LocalInventory>,

    /// Indicates which inventory fields in the provided list of
    /// [LocalInventory][google.cloud.retail.v2.LocalInventory] to update. The
    /// field is updated to the provided value.
    ///
    /// If a field is set while the place does not have a previous local inventory,
    /// the local inventory at that store is created.
    ///
    /// If a field is set while the value of that field is not provided, the
    /// original field value, if it exists, is deleted.
    ///
    /// If the mask is not set or set with empty paths, all inventory fields will
    /// be updated.
    ///
    /// If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
    /// is returned and the entire update will be ignored.
    ///
    /// [google.cloud.retail.v2.LocalInventory]: crate::model::LocalInventory
    pub add_mask: std::option::Option<wkt::FieldMask>,

    /// The time when the inventory updates are issued. Used to prevent
    /// out-of-order updates on local inventory fields. If not provided, the
    /// internal system time will be used.
    pub add_time: std::option::Option<wkt::Timestamp>,

    /// If set to true, and the [Product][google.cloud.retail.v2.Product] is not
    /// found, the local inventory will still be processed and retained for at most
    /// 1 day and processed once the [Product][google.cloud.retail.v2.Product] is
    /// created. If set to false, a NOT_FOUND error is returned if the
    /// [Product][google.cloud.retail.v2.Product] is not found.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub allow_missing: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddLocalInventoriesRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [product][crate::model::AddLocalInventoriesRequest::product].
    pub fn set_product<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.product = v.into();
        self
    }

    /// Sets the value of [local_inventories][crate::model::AddLocalInventoriesRequest::local_inventories].
    pub fn set_local_inventories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::LocalInventory>,
    {
        use std::iter::Iterator;
        self.local_inventories = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [add_mask][crate::model::AddLocalInventoriesRequest::add_mask].
    pub fn set_add_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.add_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [add_mask][crate::model::AddLocalInventoriesRequest::add_mask].
    pub fn set_or_clear_add_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.add_mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [add_time][crate::model::AddLocalInventoriesRequest::add_time].
    pub fn set_add_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.add_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [add_time][crate::model::AddLocalInventoriesRequest::add_time].
    pub fn set_or_clear_add_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.add_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_missing][crate::model::AddLocalInventoriesRequest::allow_missing].
    pub fn set_allow_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allow_missing = v.into();
        self
    }
}

impl wkt::message::Message for AddLocalInventoriesRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddLocalInventoriesRequest"
    }
}

/// Metadata related to the progress of the AddLocalInventories operation.
/// Currently empty because there is no meaningful metadata populated from the
/// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
/// method.
///
/// [google.cloud.retail.v2.ProductService.AddLocalInventories]: crate::client::ProductService::add_local_inventories
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddLocalInventoriesMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddLocalInventoriesMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for AddLocalInventoriesMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddLocalInventoriesMetadata"
    }
}

/// Response of the
/// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
/// API.  Currently empty because there is no meaningful response populated from
/// the
/// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
/// method.
///
/// [google.cloud.retail.v2.ProductService.AddLocalInventories]: crate::client::ProductService::add_local_inventories
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddLocalInventoriesResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddLocalInventoriesResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for AddLocalInventoriesResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddLocalInventoriesResponse"
    }
}

/// Request message for
/// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
/// method.
///
/// [google.cloud.retail.v2.ProductService.RemoveLocalInventories]: crate::client::ProductService::remove_local_inventories
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveLocalInventoriesRequest {
    /// Required. Full resource name of [Product][google.cloud.retail.v2.Product],
    /// such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
    ///
    /// If the caller does not have permission to access the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub product: std::string::String,

    /// Required. A list of place IDs to have their inventory deleted.
    /// At most 3000 place IDs are allowed per request.
    pub place_ids: std::vec::Vec<std::string::String>,

    /// The time when the inventory deletions are issued. Used to prevent
    /// out-of-order updates and deletions on local inventory fields. If not
    /// provided, the internal system time will be used.
    pub remove_time: std::option::Option<wkt::Timestamp>,

    /// If set to true, and the [Product][google.cloud.retail.v2.Product] is not
    /// found, the local inventory removal request will still be processed and
    /// retained for at most 1 day and processed once the
    /// [Product][google.cloud.retail.v2.Product] is created. If set to false, a
    /// NOT_FOUND error is returned if the
    /// [Product][google.cloud.retail.v2.Product] is not found.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub allow_missing: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveLocalInventoriesRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [product][crate::model::RemoveLocalInventoriesRequest::product].
    pub fn set_product<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.product = v.into();
        self
    }

    /// Sets the value of [place_ids][crate::model::RemoveLocalInventoriesRequest::place_ids].
    pub fn set_place_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.place_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [remove_time][crate::model::RemoveLocalInventoriesRequest::remove_time].
    pub fn set_remove_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.remove_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [remove_time][crate::model::RemoveLocalInventoriesRequest::remove_time].
    pub fn set_or_clear_remove_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.remove_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_missing][crate::model::RemoveLocalInventoriesRequest::allow_missing].
    pub fn set_allow_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allow_missing = v.into();
        self
    }
}

impl wkt::message::Message for RemoveLocalInventoriesRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveLocalInventoriesRequest"
    }
}

/// Metadata related to the progress of the RemoveLocalInventories operation.
/// Currently empty because there is no meaningful metadata populated from the
/// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
/// method.
///
/// [google.cloud.retail.v2.ProductService.RemoveLocalInventories]: crate::client::ProductService::remove_local_inventories
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveLocalInventoriesMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveLocalInventoriesMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for RemoveLocalInventoriesMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveLocalInventoriesMetadata"
    }
}

/// Response of the
/// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
/// API.  Currently empty because there is no meaningful response populated from
/// the
/// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
/// method.
///
/// [google.cloud.retail.v2.ProductService.RemoveLocalInventories]: crate::client::ProductService::remove_local_inventories
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveLocalInventoriesResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveLocalInventoriesResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for RemoveLocalInventoriesResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveLocalInventoriesResponse"
    }
}

/// Request message for
/// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]
/// method.
///
/// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: crate::client::ProductService::remove_fulfillment_places
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveFulfillmentPlacesRequest {
    /// Required. Full resource name of [Product][google.cloud.retail.v2.Product],
    /// such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
    ///
    /// If the caller does not have permission to access the
    /// [Product][google.cloud.retail.v2.Product], regardless of whether or not it
    /// exists, a PERMISSION_DENIED error is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub product: std::string::String,

    /// Required. The fulfillment type, including commonly used types (such as
    /// pickup in store and same day delivery), and custom types.
    ///
    /// Supported values:
    ///
    /// * "pickup-in-store"
    /// * "ship-to-store"
    /// * "same-day-delivery"
    /// * "next-day-delivery"
    /// * "custom-type-1"
    /// * "custom-type-2"
    /// * "custom-type-3"
    /// * "custom-type-4"
    /// * "custom-type-5"
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// This field directly corresponds to
    /// [Product.fulfillment_info.type][google.cloud.retail.v2.FulfillmentInfo.type].
    ///
    /// [google.cloud.retail.v2.FulfillmentInfo.type]: crate::model::FulfillmentInfo::type
    pub r#type: std::string::String,

    /// Required. The IDs for this
    /// [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type], such as
    /// the store IDs for "pickup-in-store" or the region IDs for
    /// "same-day-delivery", to be removed for this
    /// [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type].
    ///
    /// At least 1 value is required, and a maximum of 2000 values are allowed.
    /// Each value must be a string with a length limit of 10 characters, matching
    /// the pattern `[a-zA-Z0-9_-]+`, such as "store1" or "REGION-2". Otherwise, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type]: crate::model::RemoveFulfillmentPlacesRequest::type
    pub place_ids: std::vec::Vec<std::string::String>,

    /// The time when the fulfillment updates are issued, used to prevent
    /// out-of-order updates on fulfillment information. If not provided, the
    /// internal system time will be used.
    pub remove_time: std::option::Option<wkt::Timestamp>,

    /// If set to true, and the [Product][google.cloud.retail.v2.Product] is not
    /// found, the fulfillment information will still be processed and retained for
    /// at most 1 day and processed once the
    /// [Product][google.cloud.retail.v2.Product] is created. If set to false, a
    /// NOT_FOUND error is returned if the
    /// [Product][google.cloud.retail.v2.Product] is not found.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub allow_missing: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveFulfillmentPlacesRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [product][crate::model::RemoveFulfillmentPlacesRequest::product].
    pub fn set_product<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.product = v.into();
        self
    }

    /// Sets the value of [r#type][crate::model::RemoveFulfillmentPlacesRequest::type].
    pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [place_ids][crate::model::RemoveFulfillmentPlacesRequest::place_ids].
    pub fn set_place_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.place_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [remove_time][crate::model::RemoveFulfillmentPlacesRequest::remove_time].
    pub fn set_remove_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.remove_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [remove_time][crate::model::RemoveFulfillmentPlacesRequest::remove_time].
    pub fn set_or_clear_remove_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.remove_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_missing][crate::model::RemoveFulfillmentPlacesRequest::allow_missing].
    pub fn set_allow_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.allow_missing = v.into();
        self
    }
}

impl wkt::message::Message for RemoveFulfillmentPlacesRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveFulfillmentPlacesRequest"
    }
}

/// Metadata related to the progress of the RemoveFulfillmentPlaces operation.
/// Currently empty because there is no meaningful metadata populated from the
/// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]
/// method.
///
/// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: crate::client::ProductService::remove_fulfillment_places
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveFulfillmentPlacesMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveFulfillmentPlacesMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for RemoveFulfillmentPlacesMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveFulfillmentPlacesMetadata"
    }
}

/// Response of the RemoveFulfillmentPlacesRequest. Currently empty because there
/// is no meaningful response populated from the
/// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]
/// method.
///
/// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: crate::client::ProductService::remove_fulfillment_places
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveFulfillmentPlacesResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveFulfillmentPlacesResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for RemoveFulfillmentPlacesResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveFulfillmentPlacesResponse"
    }
}

/// Promotion information.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Promotion {
    /// ID of the promotion. For example, "free gift".
    ///
    /// The value must be a UTF-8 encoded string with a length limit of 128
    /// characters, and match the pattern: `[a-zA-Z][a-zA-Z0-9_]*`. For example,
    /// id0LikeThis or ID_1_LIKE_THIS. Otherwise, an INVALID_ARGUMENT error is
    /// returned.
    ///
    /// Corresponds to Google Merchant Center property
    /// [promotion_id](https://support.google.com/merchants/answer/7050148).
    pub promotion_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Promotion {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [promotion_id][crate::model::Promotion::promotion_id].
    pub fn set_promotion_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.promotion_id = v.into();
        self
    }
}

impl wkt::message::Message for Promotion {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Promotion"
    }
}

/// Metadata related to the progress of the Purge operation.
/// This will be returned by the google.longrunning.Operation.metadata field.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurgeMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurgeMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for PurgeMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurgeMetadata"
    }
}

/// Metadata related to the progress of the PurgeProducts operation.
/// This will be returned by the google.longrunning.Operation.metadata field.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurgeProductsMetadata {
    /// Operation create time.
    pub create_time: std::option::Option<wkt::Timestamp>,

    /// Operation last update time. If the operation is done, this is also the
    /// finish time.
    pub update_time: std::option::Option<wkt::Timestamp>,

    /// Count of entries that were deleted successfully.
    pub success_count: i64,

    /// Count of entries that encountered errors while processing.
    pub failure_count: i64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurgeProductsMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [create_time][crate::model::PurgeProductsMetadata::create_time].
    pub fn set_create_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [create_time][crate::model::PurgeProductsMetadata::create_time].
    pub fn set_or_clear_create_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_time][crate::model::PurgeProductsMetadata::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::PurgeProductsMetadata::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [success_count][crate::model::PurgeProductsMetadata::success_count].
    pub fn set_success_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.success_count = v.into();
        self
    }

    /// Sets the value of [failure_count][crate::model::PurgeProductsMetadata::failure_count].
    pub fn set_failure_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.failure_count = v.into();
        self
    }
}

impl wkt::message::Message for PurgeProductsMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurgeProductsMetadata"
    }
}

/// Request message for PurgeProducts method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurgeProductsRequest {
    /// Required. The resource name of the branch under which the products are
    /// created. The format is
    /// `projects/${projectId}/locations/global/catalogs/${catalogId}/branches/${branchId}`
    pub parent: std::string::String,

    /// Required. The filter string to specify the products to be deleted with a
    /// length limit of 5,000 characters.
    ///
    /// Empty string filter is not allowed. "*" implies delete all items in a
    /// branch.
    ///
    /// The eligible fields for filtering are:
    ///
    /// * `availability`: Double quoted
    ///   [Product.availability][google.cloud.retail.v2.Product.availability] string.
    /// * `create_time` : in ISO 8601 "zulu" format.
    ///
    /// Supported syntax:
    ///
    /// * Comparators (">", "<", ">=", "<=", "=").
    ///   Examples:
    ///
    ///   * create_time <= "2015-02-13T17:05:46Z"
    ///   * availability = "IN_STOCK"
    /// * Conjunctions ("AND")
    ///   Examples:
    ///
    ///   * create_time <= "2015-02-13T17:05:46Z" AND availability = "PREORDER"
    /// * Disjunctions ("OR")
    ///   Examples:
    ///
    ///   * create_time <= "2015-02-13T17:05:46Z" OR availability = "IN_STOCK"
    /// * Can support nested queries.
    ///   Examples:
    ///
    ///   * (create_time <= "2015-02-13T17:05:46Z" AND availability = "PREORDER")
    ///     OR (create_time >= "2015-02-14T13:03:32Z" AND availability = "IN_STOCK")
    /// * Filter Limits:
    ///
    ///   * Filter should not contain more than 6 conditions.
    ///   * Max nesting depth should not exceed 2 levels.
    ///
    /// Examples queries:
    ///
    /// * Delete back order products created before a timestamp.
    ///   create_time <= "2015-02-13T17:05:46Z" OR availability = "BACKORDER"
    ///
    /// [google.cloud.retail.v2.Product.availability]: crate::model::Product::availability
    pub filter: std::string::String,

    /// Actually perform the purge.
    /// If `force` is set to false, the method will return the expected purge count
    /// without deleting any products.
    pub force: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurgeProductsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::PurgeProductsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::PurgeProductsRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }

    /// Sets the value of [force][crate::model::PurgeProductsRequest::force].
    pub fn set_force<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.force = v.into();
        self
    }
}

impl wkt::message::Message for PurgeProductsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurgeProductsRequest"
    }
}

/// Response of the PurgeProductsRequest. If the long running operation is
/// successfully done, then this message is returned by the
/// google.longrunning.Operations.response field.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurgeProductsResponse {
    /// The total count of products purged as a result of the operation.
    pub purge_count: i64,

    /// A sample of the product names that will be deleted.
    /// Only populated if `force` is set to false. A max of 100 names will be
    /// returned and the names are chosen at random.
    pub purge_sample: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurgeProductsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [purge_count][crate::model::PurgeProductsResponse::purge_count].
    pub fn set_purge_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.purge_count = v.into();
        self
    }

    /// Sets the value of [purge_sample][crate::model::PurgeProductsResponse::purge_sample].
    pub fn set_purge_sample<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.purge_sample = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for PurgeProductsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurgeProductsResponse"
    }
}

/// Request message for PurgeUserEvents method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurgeUserEventsRequest {
    /// Required. The resource name of the catalog under which the events are
    /// created. The format is
    /// `projects/${projectId}/locations/global/catalogs/${catalogId}`
    pub parent: std::string::String,

    /// Required. The filter string to specify the events to be deleted with a
    /// length limit of 5,000 characters. Empty string filter is not allowed. The
    /// eligible fields for filtering are:
    ///
    /// * `eventType`: Double quoted
    ///   [UserEvent.event_type][google.cloud.retail.v2.UserEvent.event_type] string.
    /// * `eventTime`: in ISO 8601 "zulu" format.
    /// * `visitorId`: Double quoted string. Specifying this will delete all
    ///   events associated with a visitor.
    /// * `userId`: Double quoted string. Specifying this will delete all events
    ///   associated with a user.
    ///
    /// Examples:
    ///
    /// * Deleting all events in a time range:
    ///   `eventTime > "2012-04-23T18:25:43.511Z"
    ///   eventTime < "2012-04-23T18:30:43.511Z"`
    /// * Deleting specific eventType in time range:
    ///   `eventTime > "2012-04-23T18:25:43.511Z" eventType = "detail-page-view"`
    /// * Deleting all events for a specific visitor:
    ///   `visitorId = "visitor1024"`
    ///
    /// The filtering fields are assumed to have an implicit AND.
    ///
    /// [google.cloud.retail.v2.UserEvent.event_type]: crate::model::UserEvent::event_type
    pub filter: std::string::String,

    /// Actually perform the purge.
    /// If `force` is set to false, the method will return the expected purge count
    /// without deleting any user events.
    pub force: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurgeUserEventsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::PurgeUserEventsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::PurgeUserEventsRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }

    /// Sets the value of [force][crate::model::PurgeUserEventsRequest::force].
    pub fn set_force<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.force = v.into();
        self
    }
}

impl wkt::message::Message for PurgeUserEventsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurgeUserEventsRequest"
    }
}

/// Response of the PurgeUserEventsRequest. If the long running operation is
/// successfully done, then this message is returned by the
/// google.longrunning.Operations.response field.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurgeUserEventsResponse {
    /// The total count of events purged as a result of the operation.
    pub purged_events_count: i64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurgeUserEventsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [purged_events_count][crate::model::PurgeUserEventsResponse::purged_events_count].
    pub fn set_purged_events_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.purged_events_count = v.into();
        self
    }
}

impl wkt::message::Message for PurgeUserEventsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurgeUserEventsResponse"
    }
}

/// Safety settings.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SafetySetting {
    /// Harm category.
    pub category: crate::model::HarmCategory,

    /// The harm block threshold.
    pub threshold: crate::model::safety_setting::HarmBlockThreshold,

    /// Optional. Specify if the threshold is used for probability or severity
    /// score. If not specified, the threshold is used for probability score.
    pub method: crate::model::safety_setting::HarmBlockMethod,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SafetySetting {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [category][crate::model::SafetySetting::category].
    pub fn set_category<T: std::convert::Into<crate::model::HarmCategory>>(mut self, v: T) -> Self {
        self.category = v.into();
        self
    }

    /// Sets the value of [threshold][crate::model::SafetySetting::threshold].
    pub fn set_threshold<
        T: std::convert::Into<crate::model::safety_setting::HarmBlockThreshold>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.threshold = v.into();
        self
    }

    /// Sets the value of [method][crate::model::SafetySetting::method].
    pub fn set_method<T: std::convert::Into<crate::model::safety_setting::HarmBlockMethod>>(
        mut self,
        v: T,
    ) -> Self {
        self.method = v.into();
        self
    }
}

impl wkt::message::Message for SafetySetting {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SafetySetting"
    }
}

/// Defines additional types related to [SafetySetting].
pub mod safety_setting {
    #[allow(unused_imports)]
    use super::*;

    /// Probability based thresholds levels for blocking.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum HarmBlockThreshold {
        /// Unspecified harm block threshold.
        Unspecified,
        /// Block low threshold and above (i.e. block more).
        BlockLowAndAbove,
        /// Block medium threshold and above.
        BlockMediumAndAbove,
        /// Block only high threshold (i.e. block less).
        BlockOnlyHigh,
        /// Block none.
        BlockNone,
        /// Turn off the safety filter.
        Off,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [HarmBlockThreshold::value] or
        /// [HarmBlockThreshold::name].
        UnknownValue(harm_block_threshold::UnknownValue),
    }

    #[doc(hidden)]
    pub mod harm_block_threshold {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl HarmBlockThreshold {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::BlockLowAndAbove => std::option::Option::Some(1),
                Self::BlockMediumAndAbove => std::option::Option::Some(2),
                Self::BlockOnlyHigh => std::option::Option::Some(3),
                Self::BlockNone => std::option::Option::Some(4),
                Self::Off => std::option::Option::Some(5),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("HARM_BLOCK_THRESHOLD_UNSPECIFIED"),
                Self::BlockLowAndAbove => std::option::Option::Some("BLOCK_LOW_AND_ABOVE"),
                Self::BlockMediumAndAbove => std::option::Option::Some("BLOCK_MEDIUM_AND_ABOVE"),
                Self::BlockOnlyHigh => std::option::Option::Some("BLOCK_ONLY_HIGH"),
                Self::BlockNone => std::option::Option::Some("BLOCK_NONE"),
                Self::Off => std::option::Option::Some("OFF"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for HarmBlockThreshold {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for HarmBlockThreshold {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for HarmBlockThreshold {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::BlockLowAndAbove,
                2 => Self::BlockMediumAndAbove,
                3 => Self::BlockOnlyHigh,
                4 => Self::BlockNone,
                5 => Self::Off,
                _ => Self::UnknownValue(harm_block_threshold::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for HarmBlockThreshold {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "HARM_BLOCK_THRESHOLD_UNSPECIFIED" => Self::Unspecified,
                "BLOCK_LOW_AND_ABOVE" => Self::BlockLowAndAbove,
                "BLOCK_MEDIUM_AND_ABOVE" => Self::BlockMediumAndAbove,
                "BLOCK_ONLY_HIGH" => Self::BlockOnlyHigh,
                "BLOCK_NONE" => Self::BlockNone,
                "OFF" => Self::Off,
                _ => Self::UnknownValue(harm_block_threshold::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for HarmBlockThreshold {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::BlockLowAndAbove => serializer.serialize_i32(1),
                Self::BlockMediumAndAbove => serializer.serialize_i32(2),
                Self::BlockOnlyHigh => serializer.serialize_i32(3),
                Self::BlockNone => serializer.serialize_i32(4),
                Self::Off => serializer.serialize_i32(5),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for HarmBlockThreshold {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<HarmBlockThreshold>::new(
                ".google.cloud.retail.v2.SafetySetting.HarmBlockThreshold",
            ))
        }
    }

    /// Probability vs severity.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum HarmBlockMethod {
        /// The harm block method is unspecified.
        Unspecified,
        /// The harm block method uses both probability and severity scores.
        Severity,
        /// The harm block method uses the probability score.
        Probability,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [HarmBlockMethod::value] or
        /// [HarmBlockMethod::name].
        UnknownValue(harm_block_method::UnknownValue),
    }

    #[doc(hidden)]
    pub mod harm_block_method {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl HarmBlockMethod {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Severity => std::option::Option::Some(1),
                Self::Probability => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("HARM_BLOCK_METHOD_UNSPECIFIED"),
                Self::Severity => std::option::Option::Some("SEVERITY"),
                Self::Probability => std::option::Option::Some("PROBABILITY"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for HarmBlockMethod {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for HarmBlockMethod {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for HarmBlockMethod {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Severity,
                2 => Self::Probability,
                _ => Self::UnknownValue(harm_block_method::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for HarmBlockMethod {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "HARM_BLOCK_METHOD_UNSPECIFIED" => Self::Unspecified,
                "SEVERITY" => Self::Severity,
                "PROBABILITY" => Self::Probability,
                _ => Self::UnknownValue(harm_block_method::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for HarmBlockMethod {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Severity => serializer.serialize_i32(1),
                Self::Probability => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for HarmBlockMethod {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<HarmBlockMethod>::new(
                ".google.cloud.retail.v2.SafetySetting.HarmBlockMethod",
            ))
        }
    }
}

/// Product attribute which structured by an attribute name and value. This
/// structure is used in conversational search filters and answers. For example,
/// if we have `name=color` and `value=red`, this means that the color is `red`.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ProductAttributeValue {
    /// The attribute name.
    pub name: std::string::String,

    /// The attribute value.
    pub value: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ProductAttributeValue {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::ProductAttributeValue::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [value][crate::model::ProductAttributeValue::value].
    pub fn set_value<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.value = v.into();
        self
    }
}

impl wkt::message::Message for ProductAttributeValue {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ProductAttributeValue"
    }
}

/// Product attribute name and numeric interval.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ProductAttributeInterval {
    /// The attribute name (e.g. "length")
    pub name: std::string::String,

    /// The numeric interval (e.g. [10, 20))
    pub interval: std::option::Option<crate::model::Interval>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ProductAttributeInterval {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::ProductAttributeInterval::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [interval][crate::model::ProductAttributeInterval::interval].
    pub fn set_interval<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Interval>,
    {
        self.interval = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [interval][crate::model::ProductAttributeInterval::interval].
    pub fn set_or_clear_interval<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Interval>,
    {
        self.interval = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ProductAttributeInterval {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ProductAttributeInterval"
    }
}

/// This field specifies the tile information including an attribute key,
/// attribute value. More fields will be added in the future, eg: product id
/// or product counts, etc.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Tile {
    /// The representative product id for this tile.
    pub representative_product_id: std::string::String,

    /// The attribute key and value for the tile.
    pub product_attribute: std::option::Option<crate::model::tile::ProductAttribute>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Tile {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [representative_product_id][crate::model::Tile::representative_product_id].
    pub fn set_representative_product_id<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.representative_product_id = v.into();
        self
    }

    /// Sets the value of [product_attribute][crate::model::Tile::product_attribute].
    ///
    /// Note that all the setters affecting `product_attribute` are mutually
    /// exclusive.
    pub fn set_product_attribute<
        T: std::convert::Into<std::option::Option<crate::model::tile::ProductAttribute>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.product_attribute = v.into();
        self
    }

    /// The value of [product_attribute][crate::model::Tile::product_attribute]
    /// if it holds a `ProductAttributeValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn product_attribute_value(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::ProductAttributeValue>> {
        #[allow(unreachable_patterns)]
        self.product_attribute.as_ref().and_then(|v| match v {
            crate::model::tile::ProductAttribute::ProductAttributeValue(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [product_attribute][crate::model::Tile::product_attribute]
    /// to hold a `ProductAttributeValue`.
    ///
    /// Note that all the setters affecting `product_attribute` are
    /// mutually exclusive.
    pub fn set_product_attribute_value<
        T: std::convert::Into<std::boxed::Box<crate::model::ProductAttributeValue>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.product_attribute = std::option::Option::Some(
            crate::model::tile::ProductAttribute::ProductAttributeValue(v.into()),
        );
        self
    }

    /// The value of [product_attribute][crate::model::Tile::product_attribute]
    /// if it holds a `ProductAttributeInterval`, `None` if the field is not set or
    /// holds a different branch.
    pub fn product_attribute_interval(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::ProductAttributeInterval>> {
        #[allow(unreachable_patterns)]
        self.product_attribute.as_ref().and_then(|v| match v {
            crate::model::tile::ProductAttribute::ProductAttributeInterval(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [product_attribute][crate::model::Tile::product_attribute]
    /// to hold a `ProductAttributeInterval`.
    ///
    /// Note that all the setters affecting `product_attribute` are
    /// mutually exclusive.
    pub fn set_product_attribute_interval<
        T: std::convert::Into<std::boxed::Box<crate::model::ProductAttributeInterval>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.product_attribute = std::option::Option::Some(
            crate::model::tile::ProductAttribute::ProductAttributeInterval(v.into()),
        );
        self
    }
}

impl wkt::message::Message for Tile {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.Tile"
    }
}

/// Defines additional types related to [Tile].
pub mod tile {
    #[allow(unused_imports)]
    use super::*;

    /// The attribute key and value for the tile.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ProductAttribute {
        /// The product attribute key-value.
        ProductAttributeValue(std::boxed::Box<crate::model::ProductAttributeValue>),
        /// The product attribute key-numeric interval.
        ProductAttributeInterval(std::boxed::Box<crate::model::ProductAttributeInterval>),
    }
}

/// Request message for
/// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] method.
///
/// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SearchRequest {
    /// Required. The resource name of the Retail Search serving config, such as
    /// `projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`
    /// or the name of the legacy placement resource, such as
    /// `projects/*/locations/global/catalogs/default_catalog/placements/default_search`.
    /// This field is used to identify the serving config name and the set
    /// of models that are used to make the search.
    pub placement: std::string::String,

    /// The branch resource name, such as
    /// `projects/*/locations/global/catalogs/default_catalog/branches/0`.
    ///
    /// Use "default_branch" as the branch ID or leave this field empty, to search
    /// products under the default branch.
    pub branch: std::string::String,

    /// Raw search query.
    ///
    /// If this field is empty, the request is considered a category browsing
    /// request and returned results are based on
    /// [filter][google.cloud.retail.v2.SearchRequest.filter] and
    /// [page_categories][google.cloud.retail.v2.SearchRequest.page_categories].
    ///
    /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
    /// [google.cloud.retail.v2.SearchRequest.page_categories]: crate::model::SearchRequest::page_categories
    pub query: std::string::String,

    /// Required. A unique identifier for tracking visitors. For example, this
    /// could be implemented with an HTTP cookie, which should be able to uniquely
    /// identify a visitor on a single device. This unique identifier should not
    /// change if the visitor logs in or out of the website.
    ///
    /// This should be the same identifier as
    /// [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id].
    ///
    /// The field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.UserEvent.visitor_id]: crate::model::UserEvent::visitor_id
    pub visitor_id: std::string::String,

    /// User information.
    pub user_info: std::option::Option<crate::model::UserInfo>,

    /// Maximum number of [Product][google.cloud.retail.v2.Product]s to return. If
    /// unspecified, defaults to a reasonable value. The maximum allowed value is
    /// 120. Values above 120 will be coerced to 120.
    ///
    /// If this field is negative, an INVALID_ARGUMENT is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub page_size: i32,

    /// A page token
    /// [SearchResponse.next_page_token][google.cloud.retail.v2.SearchResponse.next_page_token],
    /// received from a previous
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] call.
    /// Provide this to retrieve the subsequent page.
    ///
    /// When paginating, all other parameters provided to
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] must
    /// match the call that provided the page token. Otherwise, an INVALID_ARGUMENT
    /// error is returned.
    ///
    /// [google.cloud.retail.v2.SearchResponse.next_page_token]: crate::model::SearchResponse::next_page_token
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    pub page_token: std::string::String,

    /// A 0-indexed integer that specifies the current offset (that is, starting
    /// result location, amongst the [Product][google.cloud.retail.v2.Product]s
    /// deemed by the API as relevant) in search results. This field is only
    /// considered if [page_token][google.cloud.retail.v2.SearchRequest.page_token]
    /// is unset.
    ///
    /// If this field is negative, an INVALID_ARGUMENT is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.SearchRequest.page_token]: crate::model::SearchRequest::page_token
    pub offset: i32,

    /// The filter syntax consists of an expression language for constructing a
    /// predicate from one or more fields of the products being filtered. Filter
    /// expression is case-sensitive. For more information, see
    /// [Filter](https://cloud.google.com/retail/docs/filter-and-order#filter).
    ///
    /// If this field is unrecognizable, an INVALID_ARGUMENT is returned.
    pub filter: std::string::String,

    /// The default filter that is applied when a user performs a search without
    /// checking any filters on the search page.
    ///
    /// The filter applied to every search request when quality improvement such as
    /// query expansion is needed. In the case a query does not have a sufficient
    /// amount of results this filter will be used to determine whether or not to
    /// enable the query expansion flow. The original filter will still be used for
    /// the query expanded search.
    /// This field is strongly recommended to achieve high search quality.
    ///
    /// For more information about filter syntax, see
    /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter].
    ///
    /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
    pub canonical_filter: std::string::String,

    /// The order in which products are returned. Products can be ordered by
    /// a field in an [Product][google.cloud.retail.v2.Product] object. Leave it
    /// unset if ordered by relevance. OrderBy expression is case-sensitive. For
    /// more information, see
    /// [Order](https://cloud.google.com/retail/docs/filter-and-order#order).
    ///
    /// If this field is unrecognizable, an INVALID_ARGUMENT is returned.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    pub order_by: std::string::String,

    /// Facet specifications for faceted search. If empty, no facets are returned.
    ///
    /// A maximum of 200 values are allowed. Otherwise, an INVALID_ARGUMENT error
    /// is returned.
    pub facet_specs: std::vec::Vec<crate::model::search_request::FacetSpec>,

    /// Deprecated. Refer to <https://cloud.google.com/retail/docs/configs#dynamic>
    /// to enable dynamic facets. Do not set this field.
    ///
    /// The specification for dynamically generated facets. Notice that only
    /// textual facets can be dynamically generated.
    #[deprecated]
    pub dynamic_facet_spec: std::option::Option<crate::model::search_request::DynamicFacetSpec>,

    /// Boost specification to boost certain products. For more information, see
    /// [Boost results](https://cloud.google.com/retail/docs/boosting).
    ///
    /// Notice that if both
    /// [ServingConfig.boost_control_ids][google.cloud.retail.v2.ServingConfig.boost_control_ids]
    /// and
    /// [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec]
    /// are set, the boost conditions from both places are evaluated. If a search
    /// request matches multiple boost conditions, the final boost score is equal
    /// to the sum of the boost scores from all matched boost conditions.
    ///
    /// [google.cloud.retail.v2.SearchRequest.boost_spec]: crate::model::SearchRequest::boost_spec
    /// [google.cloud.retail.v2.ServingConfig.boost_control_ids]: crate::model::ServingConfig::boost_control_ids
    pub boost_spec: std::option::Option<crate::model::search_request::BoostSpec>,

    /// The query expansion specification that specifies the conditions under which
    /// query expansion occurs. For more information, see [Query
    /// expansion](https://cloud.google.com/retail/docs/result-size#query_expansion).
    pub query_expansion_spec: std::option::Option<crate::model::search_request::QueryExpansionSpec>,

    /// The keys to fetch and rollup the matching
    /// [variant][google.cloud.retail.v2.Product.Type.VARIANT]
    /// [Product][google.cloud.retail.v2.Product]s attributes,
    /// [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo] or
    /// [LocalInventory][google.cloud.retail.v2.LocalInventory]s attributes. The
    /// attributes from all the matching
    /// [variant][google.cloud.retail.v2.Product.Type.VARIANT]
    /// [Product][google.cloud.retail.v2.Product]s or
    /// [LocalInventory][google.cloud.retail.v2.LocalInventory]s are merged and
    /// de-duplicated. Notice that rollup attributes will lead to extra query
    /// latency. Maximum number of keys is 30.
    ///
    /// For [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], a
    /// fulfillment type and a fulfillment ID must be provided in the format of
    /// "fulfillmentType.fulfillmentId". E.g., in "pickupInStore.store123",
    /// "pickupInStore" is fulfillment type and "store123" is the store ID.
    ///
    /// Supported keys are:
    ///
    /// * colorFamilies
    /// * price
    /// * originalPrice
    /// * discount
    /// * variantId
    /// * inventory(place_id,price)
    /// * inventory(place_id,original_price)
    /// * inventory(place_id,attributes.key), where key is any key in the
    ///   [Product.local_inventories.attributes][google.cloud.retail.v2.LocalInventory.attributes]
    ///   map.
    /// * attributes.key, where key is any key in the
    ///   [Product.attributes][google.cloud.retail.v2.Product.attributes] map.
    /// * pickupInStore.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "pickup-in-store".
    /// * shipToStore.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "ship-to-store".
    /// * sameDayDelivery.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "same-day-delivery".
    /// * nextDayDelivery.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "next-day-delivery".
    /// * customFulfillment1.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "custom-type-1".
    /// * customFulfillment2.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "custom-type-2".
    /// * customFulfillment3.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "custom-type-3".
    /// * customFulfillment4.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "custom-type-4".
    /// * customFulfillment5.id, where id is any
    ///   [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
    ///   for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
    ///   "custom-type-5".
    ///
    /// If this field is set to an invalid value other than these, an
    /// INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.FulfillmentInfo]: crate::model::FulfillmentInfo
    /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: crate::model::FulfillmentInfo::place_ids
    /// [google.cloud.retail.v2.FulfillmentInfo.type]: crate::model::FulfillmentInfo::type
    /// [google.cloud.retail.v2.LocalInventory]: crate::model::LocalInventory
    /// [google.cloud.retail.v2.LocalInventory.attributes]: crate::model::LocalInventory::attributes
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
    /// [google.cloud.retail.v2.Product.attributes]: crate::model::Product::attributes
    pub variant_rollup_keys: std::vec::Vec<std::string::String>,

    /// The categories associated with a category page. Must be set for category
    /// navigation queries to achieve good search quality. The format should be
    /// the same as
    /// [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories];
    ///
    /// To represent full path of category, use '>' sign to separate different
    /// hierarchies. If '>' is part of the category name, replace it with
    /// other character(s).
    ///
    /// Category pages include special pages such as sales or promotions. For
    /// instance, a special sale page may have the category hierarchy:
    /// "pageCategories" : ["Sales > 2017 Black Friday Deals"].
    ///
    /// [google.cloud.retail.v2.UserEvent.page_categories]: crate::model::UserEvent::page_categories
    pub page_categories: std::vec::Vec<std::string::String>,

    /// The search mode of the search request. If not specified, a single search
    /// request triggers both product search and faceted search.
    pub search_mode: crate::model::search_request::SearchMode,

    /// The specification for personalization.
    ///
    /// Notice that if both
    /// [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec]
    /// and
    /// [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
    /// are set.
    /// [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
    /// will override
    /// [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec].
    ///
    /// [google.cloud.retail.v2.SearchRequest.personalization_spec]: crate::model::SearchRequest::personalization_spec
    /// [google.cloud.retail.v2.ServingConfig.personalization_spec]: crate::model::ServingConfig::personalization_spec
    pub personalization_spec:
        std::option::Option<crate::model::search_request::PersonalizationSpec>,

    /// The labels applied to a resource must meet the following requirements:
    ///
    /// * Each resource can have multiple labels, up to a maximum of 64.
    /// * Each label must be a key-value pair.
    /// * Keys have a minimum length of 1 character and a maximum length of 63
    ///   characters and cannot be empty. Values can be empty and have a maximum
    ///   length of 63 characters.
    /// * Keys and values can contain only lowercase letters, numeric characters,
    ///   underscores, and dashes. All characters must use UTF-8 encoding, and
    ///   international characters are allowed.
    /// * The key portion of a label must be unique. However, you can use the same
    ///   key with multiple resources.
    /// * Keys must start with a lowercase letter or international character.
    ///
    /// For more information, see [Requirements for
    /// labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements)
    /// in the Resource Manager documentation.
    pub labels: std::collections::HashMap<std::string::String, std::string::String>,

    /// The spell correction specification that specifies the mode under
    /// which spell correction will take effect.
    pub spell_correction_spec:
        std::option::Option<crate::model::search_request::SpellCorrectionSpec>,

    /// The entity for customers that may run multiple different entities, domains,
    /// sites or regions, for example, `Google US`, `Google Ads`, `Waymo`,
    /// `google.com`, `youtube.com`, etc.
    /// If this is set, it should be exactly matched with
    /// [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] to get search
    /// results boosted by entity.
    ///
    /// [google.cloud.retail.v2.UserEvent.entity]: crate::model::UserEvent::entity
    pub entity: std::string::String,

    /// Optional. This field specifies all conversational related parameters
    /// addition to traditional retail search.
    pub conversational_search_spec:
        std::option::Option<crate::model::search_request::ConversationalSearchSpec>,

    /// Optional. This field specifies tile navigation related parameters.
    pub tile_navigation_spec: std::option::Option<crate::model::search_request::TileNavigationSpec>,

    /// Optional. The BCP-47 language code, such as "en-US" or "sr-Latn"
    /// [list](https://www.unicode.org/cldr/charts/46/summary/root.html). For more
    /// information, see [Standardized codes](https://google.aip.dev/143). This
    /// field helps to better interpret the query. If a value isn't specified, the
    /// query language code is automatically detected, which may not be accurate.
    pub language_code: std::string::String,

    /// Optional. The Unicode country/region code (CLDR) of a location, such as
    /// "US" and "419"
    /// [list](https://www.unicode.org/cldr/charts/46/supplemental/territory_information.html).
    /// For more information, see [Standardized codes](https://google.aip.dev/143).
    /// If set, then results will be boosted based on the region_code provided.
    pub region_code: std::string::String,

    /// Optional. An id corresponding to a place, such as a store id or region id.
    /// When specified, we use the price from the local inventory with the matching
    /// product's
    /// [LocalInventory.place_id][google.cloud.retail.v2.LocalInventory.place_id]
    /// for revenue optimization.
    ///
    /// [google.cloud.retail.v2.LocalInventory.place_id]: crate::model::LocalInventory::place_id
    pub place_id: std::string::String,

    /// Optional. The user attributes that could be used for personalization of
    /// search results.
    ///
    /// * Populate at most 100 key-value pairs per query.
    /// * Only supports string keys and repeated string values.
    /// * Duplicate keys are not allowed within a single query.
    ///
    /// Example:
    /// user_attributes: [
    /// { key: "pets"
    /// value {
    /// values: "dog"
    /// values: "cat"
    /// }
    /// },
    /// { key: "state"
    /// value {
    /// values: "CA"
    /// }
    /// }
    /// ]
    pub user_attributes: std::collections::HashMap<std::string::String, crate::model::StringList>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SearchRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [placement][crate::model::SearchRequest::placement].
    pub fn set_placement<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.placement = v.into();
        self
    }

    /// Sets the value of [branch][crate::model::SearchRequest::branch].
    pub fn set_branch<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.branch = v.into();
        self
    }

    /// Sets the value of [query][crate::model::SearchRequest::query].
    pub fn set_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.query = v.into();
        self
    }

    /// Sets the value of [visitor_id][crate::model::SearchRequest::visitor_id].
    pub fn set_visitor_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.visitor_id = v.into();
        self
    }

    /// Sets the value of [user_info][crate::model::SearchRequest::user_info].
    pub fn set_user_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserInfo>,
    {
        self.user_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [user_info][crate::model::SearchRequest::user_info].
    pub fn set_or_clear_user_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserInfo>,
    {
        self.user_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [page_size][crate::model::SearchRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::SearchRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [offset][crate::model::SearchRequest::offset].
    pub fn set_offset<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.offset = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::SearchRequest::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }

    /// Sets the value of [canonical_filter][crate::model::SearchRequest::canonical_filter].
    pub fn set_canonical_filter<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.canonical_filter = v.into();
        self
    }

    /// Sets the value of [order_by][crate::model::SearchRequest::order_by].
    pub fn set_order_by<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.order_by = v.into();
        self
    }

    /// Sets the value of [facet_specs][crate::model::SearchRequest::facet_specs].
    pub fn set_facet_specs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::search_request::FacetSpec>,
    {
        use std::iter::Iterator;
        self.facet_specs = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [dynamic_facet_spec][crate::model::SearchRequest::dynamic_facet_spec].
    #[deprecated]
    pub fn set_dynamic_facet_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::DynamicFacetSpec>,
    {
        self.dynamic_facet_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [dynamic_facet_spec][crate::model::SearchRequest::dynamic_facet_spec].
    #[deprecated]
    pub fn set_or_clear_dynamic_facet_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::DynamicFacetSpec>,
    {
        self.dynamic_facet_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [boost_spec][crate::model::SearchRequest::boost_spec].
    pub fn set_boost_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::BoostSpec>,
    {
        self.boost_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [boost_spec][crate::model::SearchRequest::boost_spec].
    pub fn set_or_clear_boost_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::BoostSpec>,
    {
        self.boost_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [query_expansion_spec][crate::model::SearchRequest::query_expansion_spec].
    pub fn set_query_expansion_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::QueryExpansionSpec>,
    {
        self.query_expansion_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [query_expansion_spec][crate::model::SearchRequest::query_expansion_spec].
    pub fn set_or_clear_query_expansion_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::QueryExpansionSpec>,
    {
        self.query_expansion_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [variant_rollup_keys][crate::model::SearchRequest::variant_rollup_keys].
    pub fn set_variant_rollup_keys<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.variant_rollup_keys = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [page_categories][crate::model::SearchRequest::page_categories].
    pub fn set_page_categories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.page_categories = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [search_mode][crate::model::SearchRequest::search_mode].
    pub fn set_search_mode<T: std::convert::Into<crate::model::search_request::SearchMode>>(
        mut self,
        v: T,
    ) -> Self {
        self.search_mode = v.into();
        self
    }

    /// Sets the value of [personalization_spec][crate::model::SearchRequest::personalization_spec].
    pub fn set_personalization_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::PersonalizationSpec>,
    {
        self.personalization_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [personalization_spec][crate::model::SearchRequest::personalization_spec].
    pub fn set_or_clear_personalization_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::PersonalizationSpec>,
    {
        self.personalization_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [labels][crate::model::SearchRequest::labels].
    pub fn set_labels<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.labels = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [spell_correction_spec][crate::model::SearchRequest::spell_correction_spec].
    pub fn set_spell_correction_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::SpellCorrectionSpec>,
    {
        self.spell_correction_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [spell_correction_spec][crate::model::SearchRequest::spell_correction_spec].
    pub fn set_or_clear_spell_correction_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::SpellCorrectionSpec>,
    {
        self.spell_correction_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [entity][crate::model::SearchRequest::entity].
    pub fn set_entity<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.entity = v.into();
        self
    }

    /// Sets the value of [conversational_search_spec][crate::model::SearchRequest::conversational_search_spec].
    pub fn set_conversational_search_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::ConversationalSearchSpec>,
    {
        self.conversational_search_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [conversational_search_spec][crate::model::SearchRequest::conversational_search_spec].
    pub fn set_or_clear_conversational_search_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::ConversationalSearchSpec>,
    {
        self.conversational_search_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [tile_navigation_spec][crate::model::SearchRequest::tile_navigation_spec].
    pub fn set_tile_navigation_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::TileNavigationSpec>,
    {
        self.tile_navigation_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [tile_navigation_spec][crate::model::SearchRequest::tile_navigation_spec].
    pub fn set_or_clear_tile_navigation_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::TileNavigationSpec>,
    {
        self.tile_navigation_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [language_code][crate::model::SearchRequest::language_code].
    pub fn set_language_code<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.language_code = v.into();
        self
    }

    /// Sets the value of [region_code][crate::model::SearchRequest::region_code].
    pub fn set_region_code<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.region_code = v.into();
        self
    }

    /// Sets the value of [place_id][crate::model::SearchRequest::place_id].
    pub fn set_place_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.place_id = v.into();
        self
    }

    /// Sets the value of [user_attributes][crate::model::SearchRequest::user_attributes].
    pub fn set_user_attributes<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::StringList>,
    {
        use std::iter::Iterator;
        self.user_attributes = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for SearchRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SearchRequest"
    }
}

/// Defines additional types related to [SearchRequest].
pub mod search_request {
    #[allow(unused_imports)]
    use super::*;

    /// A facet specification to perform faceted search.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FacetSpec {
        /// Required. The facet key specification.
        pub facet_key: std::option::Option<crate::model::search_request::facet_spec::FacetKey>,

        /// Maximum of facet values that should be returned for this facet. If
        /// unspecified, defaults to 50. The maximum allowed value is 300. Values
        /// above 300 will be coerced to 300.
        ///
        /// If this field is negative, an INVALID_ARGUMENT is returned.
        pub limit: i32,

        /// List of keys to exclude when faceting.
        ///
        /// By default,
        /// [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
        /// is not excluded from the filter unless it is listed in this field.
        ///
        /// Listing a facet key in this field allows its values to appear as facet
        /// results, even when they are filtered out of search results. Using this
        /// field does not affect what search results are returned.
        ///
        /// For example, suppose there are 100 products with the color facet "Red"
        /// and 200 products with the color facet "Blue". A query containing the
        /// filter "colorFamilies:ANY("Red")" and having "colorFamilies" as
        /// [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
        /// would by default return only "Red" products in the search results, and
        /// also return "Red" with count 100 as the only color facet. Although there
        /// are also blue products available, "Blue" would not be shown as an
        /// available facet value.
        ///
        /// If "colorFamilies" is listed in "excludedFilterKeys", then the query
        /// returns the facet values "Red" with count 100 and "Blue" with count
        /// 200, because the "colorFamilies" key is now excluded from the filter.
        /// Because this field doesn't affect search results, the search results
        /// are still correctly filtered to return only "Red" products.
        ///
        /// A maximum of 100 values are allowed. Otherwise, an INVALID_ARGUMENT error
        /// is returned.
        ///
        /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]: crate::model::search_request::facet_spec::FacetKey::key
        pub excluded_filter_keys: std::vec::Vec<std::string::String>,

        /// Enables dynamic position for this facet. If set to true, the position of
        /// this facet among all facets in the response is determined by Google
        /// Retail Search. It is ordered together with dynamic facets if dynamic
        /// facets is enabled. If set to false, the position of this facet in the
        /// response is the same as in the request, and it is ranked before
        /// the facets with dynamic position enable and all dynamic facets.
        ///
        /// For example, you may always want to have rating facet returned in
        /// the response, but it's not necessarily to always display the rating facet
        /// at the top. In that case, you can set enable_dynamic_position to true so
        /// that the position of rating facet in response is determined by
        /// Google Retail Search.
        ///
        /// Another example, assuming you have the following facets in the request:
        ///
        /// * "rating", enable_dynamic_position = true
        ///
        /// * "price", enable_dynamic_position = false
        ///
        /// * "brands", enable_dynamic_position = false
        ///
        ///
        /// And also you have a dynamic facets enable, which generates a facet
        /// "gender". Then, the final order of the facets in the response can be
        /// ("price", "brands", "rating", "gender") or ("price", "brands", "gender",
        /// "rating") depends on how Google Retail Search orders "gender" and
        /// "rating" facets. However, notice that "price" and "brands" are always
        /// ranked at first and second position because their enable_dynamic_position
        /// values are false.
        pub enable_dynamic_position: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FacetSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [facet_key][crate::model::search_request::FacetSpec::facet_key].
        pub fn set_facet_key<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::search_request::facet_spec::FacetKey>,
        {
            self.facet_key = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [facet_key][crate::model::search_request::FacetSpec::facet_key].
        pub fn set_or_clear_facet_key<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::search_request::facet_spec::FacetKey>,
        {
            self.facet_key = v.map(|x| x.into());
            self
        }

        /// Sets the value of [limit][crate::model::search_request::FacetSpec::limit].
        pub fn set_limit<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.limit = v.into();
            self
        }

        /// Sets the value of [excluded_filter_keys][crate::model::search_request::FacetSpec::excluded_filter_keys].
        pub fn set_excluded_filter_keys<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.excluded_filter_keys = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [enable_dynamic_position][crate::model::search_request::FacetSpec::enable_dynamic_position].
        pub fn set_enable_dynamic_position<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.enable_dynamic_position = v.into();
            self
        }
    }

    impl wkt::message::Message for FacetSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.FacetSpec"
        }
    }

    /// Defines additional types related to [FacetSpec].
    pub mod facet_spec {
        #[allow(unused_imports)]
        use super::*;

        /// Specifies how a facet is computed.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct FacetKey {
            /// Required. Supported textual and numerical facet keys in
            /// [Product][google.cloud.retail.v2.Product] object, over which the facet
            /// values are computed. Facet key is case-sensitive.
            ///
            /// Allowed facet keys when
            /// [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query]
            /// is not specified:
            ///
            /// * textual_field =
            ///
            ///   * "brands"
            ///   * "categories"
            ///   * "genders"
            ///   * "ageGroups"
            ///   * "availability"
            ///   * "colorFamilies"
            ///   * "colors"
            ///   * "sizes"
            ///   * "materials"
            ///   * "patterns"
            ///   * "conditions"
            ///   * "attributes.key"
            ///   * "pickupInStore"
            ///   * "shipToStore"
            ///   * "sameDayDelivery"
            ///   * "nextDayDelivery"
            ///   * "customFulfillment1"
            ///   * "customFulfillment2"
            ///   * "customFulfillment3"
            ///   * "customFulfillment4"
            ///   * "customFulfillment5"
            ///   * "inventory(place_id,attributes.key)"
            /// * numerical_field =
            ///
            ///   * "price"
            ///   * "discount"
            ///   * "rating"
            ///   * "ratingCount"
            ///   * "attributes.key"
            ///   * "inventory(place_id,price)"
            ///   * "inventory(place_id,original_price)"
            ///   * "inventory(place_id,attributes.key)"
            ///
            /// [google.cloud.retail.v2.Product]: crate::model::Product
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query]: crate::model::search_request::facet_spec::FacetKey::query
            pub key: std::string::String,

            /// Set only if values should be bucketized into intervals. Must be set
            /// for facets with numerical values. Must not be set for facet with text
            /// values. Maximum number of intervals is 40.
            ///
            /// For all numerical facet keys that appear in the list of products from
            /// the catalog, the percentiles 0, 10, 30, 50, 70, 90, and 100 are
            /// computed from their distribution weekly. If the model assigns a high
            /// score to a numerical facet key and its intervals are not specified in
            /// the search request, these percentiles become the bounds
            /// for its intervals and are returned in the response. If the
            /// facet key intervals are specified in the request, then the specified
            /// intervals are returned instead.
            pub intervals: std::vec::Vec<crate::model::Interval>,

            /// Only get facet for the given restricted values. For example, when using
            /// "pickupInStore" as key and set restricted values to
            /// ["store123", "store456"], only facets for "store123" and "store456" are
            /// returned. Only supported on predefined textual fields, custom textual
            /// attributes and fulfillments. Maximum is 20.
            ///
            /// Must be set for the fulfillment facet keys:
            ///
            /// * pickupInStore
            ///
            /// * shipToStore
            ///
            /// * sameDayDelivery
            ///
            /// * nextDayDelivery
            ///
            /// * customFulfillment1
            ///
            /// * customFulfillment2
            ///
            /// * customFulfillment3
            ///
            /// * customFulfillment4
            ///
            /// * customFulfillment5
            ///
            pub restricted_values: std::vec::Vec<std::string::String>,

            /// Only get facet values that start with the given string prefix. For
            /// example, suppose "categories" has three values "Women > Shoe",
            /// "Women > Dress" and "Men > Shoe". If set "prefixes" to "Women", the
            /// "categories" facet gives only "Women > Shoe" and "Women > Dress".
            /// Only supported on textual fields. Maximum is 10.
            pub prefixes: std::vec::Vec<std::string::String>,

            /// Only get facet values that contains the given strings. For example,
            /// suppose "categories" has three values "Women > Shoe",
            /// "Women > Dress" and "Men > Shoe". If set "contains" to "Shoe", the
            /// "categories" facet gives only "Women > Shoe" and "Men > Shoe".
            /// Only supported on textual fields. Maximum is 10.
            pub contains: std::vec::Vec<std::string::String>,

            /// True to make facet keys case insensitive when getting faceting
            /// values with prefixes or contains; false otherwise.
            pub case_insensitive: bool,

            /// The order in which
            /// [SearchResponse.Facet.values][google.cloud.retail.v2.SearchResponse.Facet.values]
            /// are returned.
            ///
            /// Allowed values are:
            ///
            /// * "count desc", which means order by
            ///   [SearchResponse.Facet.values.count][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count]
            ///   descending.
            ///
            /// * "value desc", which means order by
            ///   [SearchResponse.Facet.values.value][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value]
            ///   descending.
            ///   Only applies to textual facets.
            ///
            ///
            /// If not set, textual values are sorted in [natural
            /// order](https://en.wikipedia.org/wiki/Natural_sort_order); numerical
            /// intervals are sorted in the order given by
            /// [FacetSpec.FacetKey.intervals][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals];
            /// [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
            /// are sorted in the order given by
            /// [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.restricted_values].
            ///
            /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: crate::model::FulfillmentInfo::place_ids
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals]: crate::model::search_request::facet_spec::FacetKey::intervals
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.restricted_values]: crate::model::search_request::facet_spec::FacetKey::restricted_values
            /// [google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count]: crate::model::search_response::facet::FacetValue::count
            /// [google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value]: crate::model::search_response::facet::FacetValue::facet_value
            /// [google.cloud.retail.v2.SearchResponse.Facet.values]: crate::model::search_response::Facet::values
            pub order_by: std::string::String,

            /// The query that is used to compute facet for the given facet key.
            /// When provided, it overrides the default behavior of facet
            /// computation. The query syntax is the same as a filter expression. See
            /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
            /// detail syntax and limitations. Notice that there is no limitation on
            /// [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
            /// when query is specified.
            ///
            /// In the response,
            /// [SearchResponse.Facet.values.value][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value]
            /// is always "1" and
            /// [SearchResponse.Facet.values.count][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count]
            /// is the number of results that match the query.
            ///
            /// For example, you can set a customized facet for "shipToStore",
            /// where
            /// [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
            /// is "customizedShipToStore", and
            /// [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query]
            /// is "availability: ANY(\"IN_STOCK\") AND shipToStore: ANY(\"123\")".
            /// Then the facet counts the products that are both in stock and ship
            /// to store "123".
            ///
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]: crate::model::search_request::facet_spec::FacetKey::key
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query]: crate::model::search_request::facet_spec::FacetKey::query
            /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
            /// [google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count]: crate::model::search_response::facet::FacetValue::count
            /// [google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value]: crate::model::search_response::facet::FacetValue::facet_value
            pub query: std::string::String,

            /// Returns the min and max value for each numerical facet intervals.
            /// Ignored for textual facets.
            pub return_min_max: bool,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl FacetKey {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [key][crate::model::search_request::facet_spec::FacetKey::key].
            pub fn set_key<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
                self.key = v.into();
                self
            }

            /// Sets the value of [intervals][crate::model::search_request::facet_spec::FacetKey::intervals].
            pub fn set_intervals<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<crate::model::Interval>,
            {
                use std::iter::Iterator;
                self.intervals = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [restricted_values][crate::model::search_request::facet_spec::FacetKey::restricted_values].
            pub fn set_restricted_values<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<std::string::String>,
            {
                use std::iter::Iterator;
                self.restricted_values = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [prefixes][crate::model::search_request::facet_spec::FacetKey::prefixes].
            pub fn set_prefixes<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<std::string::String>,
            {
                use std::iter::Iterator;
                self.prefixes = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [contains][crate::model::search_request::facet_spec::FacetKey::contains].
            pub fn set_contains<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<std::string::String>,
            {
                use std::iter::Iterator;
                self.contains = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [case_insensitive][crate::model::search_request::facet_spec::FacetKey::case_insensitive].
            pub fn set_case_insensitive<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
                self.case_insensitive = v.into();
                self
            }

            /// Sets the value of [order_by][crate::model::search_request::facet_spec::FacetKey::order_by].
            pub fn set_order_by<T: std::convert::Into<std::string::String>>(
                mut self,
                v: T,
            ) -> Self {
                self.order_by = v.into();
                self
            }

            /// Sets the value of [query][crate::model::search_request::facet_spec::FacetKey::query].
            pub fn set_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
                self.query = v.into();
                self
            }

            /// Sets the value of [return_min_max][crate::model::search_request::facet_spec::FacetKey::return_min_max].
            pub fn set_return_min_max<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
                self.return_min_max = v.into();
                self
            }
        }

        impl wkt::message::Message for FacetKey {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey"
            }
        }
    }

    /// The specifications of dynamically generated facets.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct DynamicFacetSpec {
        /// Mode of the DynamicFacet feature.
        /// Defaults to
        /// [Mode.DISABLED][google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode.DISABLED]
        /// if it's unset.
        ///
        /// [google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode.DISABLED]: crate::model::search_request::dynamic_facet_spec::Mode::Disabled
        pub mode: crate::model::search_request::dynamic_facet_spec::Mode,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl DynamicFacetSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [mode][crate::model::search_request::DynamicFacetSpec::mode].
        pub fn set_mode<
            T: std::convert::Into<crate::model::search_request::dynamic_facet_spec::Mode>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.mode = v.into();
            self
        }
    }

    impl wkt::message::Message for DynamicFacetSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.DynamicFacetSpec"
        }
    }

    /// Defines additional types related to [DynamicFacetSpec].
    pub mod dynamic_facet_spec {
        #[allow(unused_imports)]
        use super::*;

        /// Enum to control DynamicFacet mode
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Mode {
            /// Default value.
            Unspecified,
            /// Disable Dynamic Facet.
            Disabled,
            /// Automatic mode built by Google Retail Search.
            Enabled,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Mode::value] or
            /// [Mode::name].
            UnknownValue(mode::UnknownValue),
        }

        #[doc(hidden)]
        pub mod mode {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Mode {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::Disabled => std::option::Option::Some(1),
                    Self::Enabled => std::option::Option::Some(2),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("MODE_UNSPECIFIED"),
                    Self::Disabled => std::option::Option::Some("DISABLED"),
                    Self::Enabled => std::option::Option::Some("ENABLED"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Mode {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Mode {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Mode {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::Disabled,
                    2 => Self::Enabled,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Mode {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "MODE_UNSPECIFIED" => Self::Unspecified,
                    "DISABLED" => Self::Disabled,
                    "ENABLED" => Self::Enabled,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Mode {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::Disabled => serializer.serialize_i32(1),
                    Self::Enabled => serializer.serialize_i32(2),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Mode {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Mode>::new(
                    ".google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode",
                ))
            }
        }
    }

    /// Boost specification to boost certain items.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct BoostSpec {
        /// Condition boost specifications. If a product matches multiple conditions
        /// in the specifications, boost scores from these specifications are all
        /// applied and combined in a non-linear way. Maximum number of
        /// specifications is 20.
        pub condition_boost_specs:
            std::vec::Vec<crate::model::search_request::boost_spec::ConditionBoostSpec>,

        /// Whether to skip boostspec validation. If this field is set to true,
        /// invalid
        /// [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]
        /// will be ignored and valid
        /// [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]
        /// will still be applied.
        ///
        /// [google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]: crate::model::search_request::BoostSpec::condition_boost_specs
        pub skip_boost_spec_validation: std::option::Option<bool>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl BoostSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [condition_boost_specs][crate::model::search_request::BoostSpec::condition_boost_specs].
        pub fn set_condition_boost_specs<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::search_request::boost_spec::ConditionBoostSpec>,
        {
            use std::iter::Iterator;
            self.condition_boost_specs = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [skip_boost_spec_validation][crate::model::search_request::BoostSpec::skip_boost_spec_validation].
        pub fn set_skip_boost_spec_validation<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<bool>,
        {
            self.skip_boost_spec_validation = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [skip_boost_spec_validation][crate::model::search_request::BoostSpec::skip_boost_spec_validation].
        pub fn set_or_clear_skip_boost_spec_validation<T>(
            mut self,
            v: std::option::Option<T>,
        ) -> Self
        where
            T: std::convert::Into<bool>,
        {
            self.skip_boost_spec_validation = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for BoostSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.BoostSpec"
        }
    }

    /// Defines additional types related to [BoostSpec].
    pub mod boost_spec {
        #[allow(unused_imports)]
        use super::*;

        /// Boost applies to products which match a condition.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct ConditionBoostSpec {
            /// An expression which specifies a boost condition. The syntax and
            /// supported fields are the same as a filter expression. See
            /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
            /// detail syntax and limitations.
            ///
            /// Examples:
            ///
            /// * To boost products with product ID "product_1" or "product_2", and
            ///   color
            ///   "Red" or "Blue":
            ///   * (id: ANY("product_1", "product_2")) AND (colorFamilies:
            ///     ANY("Red","Blue"))
            ///
            /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
            pub condition: std::string::String,

            /// Strength of the condition boost, which should be in [-1, 1]. Negative
            /// boost means demotion. Default is 0.0.
            ///
            /// Setting to 1.0 gives the item a big promotion. However, it does not
            /// necessarily mean that the boosted item will be the top result at all
            /// times, nor that other items will be excluded. Results could still be
            /// shown even when none of them matches the condition. And results that
            /// are significantly more relevant to the search query can still trump
            /// your heavily favored but irrelevant items.
            ///
            /// Setting to -1.0 gives the item a big demotion. However, results that
            /// are deeply relevant might still be shown. The item will have an
            /// upstream battle to get a fairly high ranking, but it is not blocked out
            /// completely.
            ///
            /// Setting to 0.0 means no boost applied. The boosting condition is
            /// ignored.
            pub boost: f32,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl ConditionBoostSpec {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [condition][crate::model::search_request::boost_spec::ConditionBoostSpec::condition].
            pub fn set_condition<T: std::convert::Into<std::string::String>>(
                mut self,
                v: T,
            ) -> Self {
                self.condition = v.into();
                self
            }

            /// Sets the value of [boost][crate::model::search_request::boost_spec::ConditionBoostSpec::boost].
            pub fn set_boost<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
                self.boost = v.into();
                self
            }
        }

        impl wkt::message::Message for ConditionBoostSpec {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.SearchRequest.BoostSpec.ConditionBoostSpec"
            }
        }
    }

    /// Specification to determine under which conditions query expansion should
    /// occur.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct QueryExpansionSpec {
        /// The condition under which query expansion should occur. Default to
        /// [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED].
        ///
        /// [google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED]: crate::model::search_request::query_expansion_spec::Condition::Disabled
        pub condition: crate::model::search_request::query_expansion_spec::Condition,

        /// Whether to pin unexpanded results. The default value is false. If this
        /// field is set to true,
        /// unexpanded products are always at the top of the search results, followed
        /// by the expanded results.
        pub pin_unexpanded_results: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl QueryExpansionSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [condition][crate::model::search_request::QueryExpansionSpec::condition].
        pub fn set_condition<
            T: std::convert::Into<crate::model::search_request::query_expansion_spec::Condition>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.condition = v.into();
            self
        }

        /// Sets the value of [pin_unexpanded_results][crate::model::search_request::QueryExpansionSpec::pin_unexpanded_results].
        pub fn set_pin_unexpanded_results<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.pin_unexpanded_results = v.into();
            self
        }
    }

    impl wkt::message::Message for QueryExpansionSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.QueryExpansionSpec"
        }
    }

    /// Defines additional types related to [QueryExpansionSpec].
    pub mod query_expansion_spec {
        #[allow(unused_imports)]
        use super::*;

        /// Enum describing under which condition query expansion should occur.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Condition {
            /// Unspecified query expansion condition. In this case, server behavior
            /// defaults to
            /// [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED].
            ///
            /// [google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED]: crate::model::search_request::query_expansion_spec::Condition::Disabled
            Unspecified,
            /// Disabled query expansion. Only the exact search query is used, even if
            /// [SearchResponse.total_size][google.cloud.retail.v2.SearchResponse.total_size]
            /// is zero.
            ///
            /// [google.cloud.retail.v2.SearchResponse.total_size]: crate::model::SearchResponse::total_size
            Disabled,
            /// Automatic query expansion built by Google Retail Search.
            Auto,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Condition::value] or
            /// [Condition::name].
            UnknownValue(condition::UnknownValue),
        }

        #[doc(hidden)]
        pub mod condition {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Condition {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::Disabled => std::option::Option::Some(1),
                    Self::Auto => std::option::Option::Some(3),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("CONDITION_UNSPECIFIED"),
                    Self::Disabled => std::option::Option::Some("DISABLED"),
                    Self::Auto => std::option::Option::Some("AUTO"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Condition {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Condition {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Condition {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::Disabled,
                    3 => Self::Auto,
                    _ => Self::UnknownValue(condition::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Condition {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "CONDITION_UNSPECIFIED" => Self::Unspecified,
                    "DISABLED" => Self::Disabled,
                    "AUTO" => Self::Auto,
                    _ => Self::UnknownValue(condition::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Condition {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::Disabled => serializer.serialize_i32(1),
                    Self::Auto => serializer.serialize_i32(3),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Condition {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Condition>::new(
                    ".google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition",
                ))
            }
        }
    }

    /// The specification for personalization.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct PersonalizationSpec {
        /// Defaults to
        /// [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO].
        ///
        /// [google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]: crate::model::search_request::personalization_spec::Mode::Auto
        pub mode: crate::model::search_request::personalization_spec::Mode,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl PersonalizationSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [mode][crate::model::search_request::PersonalizationSpec::mode].
        pub fn set_mode<
            T: std::convert::Into<crate::model::search_request::personalization_spec::Mode>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.mode = v.into();
            self
        }
    }

    impl wkt::message::Message for PersonalizationSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.PersonalizationSpec"
        }
    }

    /// Defines additional types related to [PersonalizationSpec].
    pub mod personalization_spec {
        #[allow(unused_imports)]
        use super::*;

        /// The personalization mode of each search request.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Mode {
            /// Default value. In this case, server behavior defaults to
            /// [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO].
            ///
            /// [google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]: crate::model::search_request::personalization_spec::Mode::Auto
            Unspecified,
            /// Let CRS decide whether to use personalization based on quality of user
            /// event data.
            Auto,
            /// Disable personalization.
            Disabled,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Mode::value] or
            /// [Mode::name].
            UnknownValue(mode::UnknownValue),
        }

        #[doc(hidden)]
        pub mod mode {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Mode {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::Auto => std::option::Option::Some(1),
                    Self::Disabled => std::option::Option::Some(2),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("MODE_UNSPECIFIED"),
                    Self::Auto => std::option::Option::Some("AUTO"),
                    Self::Disabled => std::option::Option::Some("DISABLED"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Mode {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Mode {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Mode {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::Auto,
                    2 => Self::Disabled,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Mode {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "MODE_UNSPECIFIED" => Self::Unspecified,
                    "AUTO" => Self::Auto,
                    "DISABLED" => Self::Disabled,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Mode {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::Auto => serializer.serialize_i32(1),
                    Self::Disabled => serializer.serialize_i32(2),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Mode {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Mode>::new(
                    ".google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode",
                ))
            }
        }
    }

    /// The specification for query spell correction.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct SpellCorrectionSpec {
        /// The mode under which spell correction should take effect to
        /// replace the original search query. Default to
        /// [Mode.AUTO][google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO].
        ///
        /// [google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO]: crate::model::search_request::spell_correction_spec::Mode::Auto
        pub mode: crate::model::search_request::spell_correction_spec::Mode,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl SpellCorrectionSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [mode][crate::model::search_request::SpellCorrectionSpec::mode].
        pub fn set_mode<
            T: std::convert::Into<crate::model::search_request::spell_correction_spec::Mode>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.mode = v.into();
            self
        }
    }

    impl wkt::message::Message for SpellCorrectionSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec"
        }
    }

    /// Defines additional types related to [SpellCorrectionSpec].
    pub mod spell_correction_spec {
        #[allow(unused_imports)]
        use super::*;

        /// Enum describing under which mode spell correction should occur.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Mode {
            /// Unspecified spell correction mode. In this case, server behavior
            /// defaults to
            /// [Mode.AUTO][google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO].
            ///
            /// [google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO]: crate::model::search_request::spell_correction_spec::Mode::Auto
            Unspecified,
            /// Google Retail Search will try to find a spell suggestion if there
            /// is any and put in the
            /// [SearchResponse.corrected_query][google.cloud.retail.v2.SearchResponse.corrected_query].
            /// The spell suggestion will not be used as the search query.
            ///
            /// [google.cloud.retail.v2.SearchResponse.corrected_query]: crate::model::SearchResponse::corrected_query
            SuggestionOnly,
            /// Automatic spell correction built by Google Retail Search. Search will
            /// be based on the corrected query if found.
            Auto,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Mode::value] or
            /// [Mode::name].
            UnknownValue(mode::UnknownValue),
        }

        #[doc(hidden)]
        pub mod mode {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Mode {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::SuggestionOnly => std::option::Option::Some(1),
                    Self::Auto => std::option::Option::Some(2),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("MODE_UNSPECIFIED"),
                    Self::SuggestionOnly => std::option::Option::Some("SUGGESTION_ONLY"),
                    Self::Auto => std::option::Option::Some("AUTO"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Mode {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Mode {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Mode {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::SuggestionOnly,
                    2 => Self::Auto,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Mode {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "MODE_UNSPECIFIED" => Self::Unspecified,
                    "SUGGESTION_ONLY" => Self::SuggestionOnly,
                    "AUTO" => Self::Auto,
                    _ => Self::UnknownValue(mode::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Mode {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::SuggestionOnly => serializer.serialize_i32(1),
                    Self::Auto => serializer.serialize_i32(2),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Mode {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Mode>::new(
                    ".google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode",
                ))
            }
        }
    }

    /// This field specifies all conversational related parameters addition to
    /// traditional retail search.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ConversationalSearchSpec {
        /// This field specifies whether the customer would like to do conversational
        /// search. If this field is set to true, conversational related extra
        /// information will be returned from server side, including follow-up
        /// question, answer options, etc.
        pub followup_conversation_requested: bool,

        /// This field specifies the conversation id, which maintains the state of
        /// the conversation between client side and server side. Use the value from
        /// the previous [ConversationalSearchResult.conversation_id][]. For the
        /// initial request, this should be empty.
        pub conversation_id: std::string::String,

        /// This field specifies the current user answer during the conversational
        /// search. This can be either user selected from suggested answers or user
        /// input plain text.
        pub user_answer: std::option::Option<
            crate::model::search_request::conversational_search_spec::UserAnswer,
        >,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ConversationalSearchSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [followup_conversation_requested][crate::model::search_request::ConversationalSearchSpec::followup_conversation_requested].
        pub fn set_followup_conversation_requested<T: std::convert::Into<bool>>(
            mut self,
            v: T,
        ) -> Self {
            self.followup_conversation_requested = v.into();
            self
        }

        /// Sets the value of [conversation_id][crate::model::search_request::ConversationalSearchSpec::conversation_id].
        pub fn set_conversation_id<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.conversation_id = v.into();
            self
        }

        /// Sets the value of [user_answer][crate::model::search_request::ConversationalSearchSpec::user_answer].
        pub fn set_user_answer<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<
                    crate::model::search_request::conversational_search_spec::UserAnswer,
                >,
        {
            self.user_answer = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [user_answer][crate::model::search_request::ConversationalSearchSpec::user_answer].
        pub fn set_or_clear_user_answer<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<
                    crate::model::search_request::conversational_search_spec::UserAnswer,
                >,
        {
            self.user_answer = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for ConversationalSearchSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec"
        }
    }

    /// Defines additional types related to [ConversationalSearchSpec].
    pub mod conversational_search_spec {
        #[allow(unused_imports)]
        use super::*;

        /// This field specifies the current user answer during the conversational
        /// search. This can be either user selected from suggested answers or user
        /// input plain text.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct UserAnswer {
            /// This field specifies the type of user answer.
            pub r#type: std::option::Option<
                crate::model::search_request::conversational_search_spec::user_answer::Type,
            >,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl UserAnswer {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [r#type][crate::model::search_request::conversational_search_spec::UserAnswer::type].
            ///
            /// Note that all the setters affecting `r#type` are mutually
            /// exclusive.
            pub fn set_type<T: std::convert::Into<std::option::Option<crate::model::search_request::conversational_search_spec::user_answer::Type>>>(mut self, v: T) -> Self
            {
                self.r#type = v.into();
                self
            }

            /// The value of [r#type][crate::model::search_request::conversational_search_spec::UserAnswer::r#type]
            /// if it holds a `TextAnswer`, `None` if the field is not set or
            /// holds a different branch.
            pub fn text_answer(&self) -> std::option::Option<&std::string::String> {
                #[allow(unreachable_patterns)]
                self.r#type.as_ref().and_then(|v| match v {
                    crate::model::search_request::conversational_search_spec::user_answer::Type::TextAnswer(v) => std::option::Option::Some(v),
                    _ => std::option::Option::None,
                })
            }

            /// Sets the value of [r#type][crate::model::search_request::conversational_search_spec::UserAnswer::r#type]
            /// to hold a `TextAnswer`.
            ///
            /// Note that all the setters affecting `r#type` are
            /// mutually exclusive.
            pub fn set_text_answer<T: std::convert::Into<std::string::String>>(
                mut self,
                v: T,
            ) -> Self {
                self.r#type = std::option::Option::Some(
                    crate::model::search_request::conversational_search_spec::user_answer::Type::TextAnswer(
                        v.into()
                    )
                );
                self
            }

            /// The value of [r#type][crate::model::search_request::conversational_search_spec::UserAnswer::r#type]
            /// if it holds a `SelectedAnswer`, `None` if the field is not set or
            /// holds a different branch.
            pub fn selected_answer(&self) -> std::option::Option<&std::boxed::Box<crate::model::search_request::conversational_search_spec::user_answer::SelectedAnswer>>{
                #[allow(unreachable_patterns)]
                self.r#type.as_ref().and_then(|v| match v {
                    crate::model::search_request::conversational_search_spec::user_answer::Type::SelectedAnswer(v) => std::option::Option::Some(v),
                    _ => std::option::Option::None,
                })
            }

            /// Sets the value of [r#type][crate::model::search_request::conversational_search_spec::UserAnswer::r#type]
            /// to hold a `SelectedAnswer`.
            ///
            /// Note that all the setters affecting `r#type` are
            /// mutually exclusive.
            pub fn set_selected_answer<T: std::convert::Into<std::boxed::Box<crate::model::search_request::conversational_search_spec::user_answer::SelectedAnswer>>>(mut self, v: T) -> Self{
                self.r#type = std::option::Option::Some(
                    crate::model::search_request::conversational_search_spec::user_answer::Type::SelectedAnswer(
                        v.into()
                    )
                );
                self
            }
        }

        impl wkt::message::Message for UserAnswer {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec.UserAnswer"
            }
        }

        /// Defines additional types related to [UserAnswer].
        pub mod user_answer {
            #[allow(unused_imports)]
            use super::*;

            /// This field specifies the selected answers during the conversational
            /// search.
            #[derive(Clone, Default, PartialEq)]
            #[non_exhaustive]
            pub struct SelectedAnswer {
                /// This field is deprecated and should not be set.
                #[deprecated]
                pub product_attribute_values: std::vec::Vec<crate::model::ProductAttributeValue>,

                /// This field specifies the selected answer which is a attribute
                /// key-value.
                pub product_attribute_value:
                    std::option::Option<crate::model::ProductAttributeValue>,

                pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
            }

            impl SelectedAnswer {
                pub fn new() -> Self {
                    std::default::Default::default()
                }

                /// Sets the value of [product_attribute_values][crate::model::search_request::conversational_search_spec::user_answer::SelectedAnswer::product_attribute_values].
                #[deprecated]
                pub fn set_product_attribute_values<T, V>(mut self, v: T) -> Self
                where
                    T: std::iter::IntoIterator<Item = V>,
                    V: std::convert::Into<crate::model::ProductAttributeValue>,
                {
                    use std::iter::Iterator;
                    self.product_attribute_values = v.into_iter().map(|i| i.into()).collect();
                    self
                }

                /// Sets the value of [product_attribute_value][crate::model::search_request::conversational_search_spec::user_answer::SelectedAnswer::product_attribute_value].
                pub fn set_product_attribute_value<T>(mut self, v: T) -> Self
                where
                    T: std::convert::Into<crate::model::ProductAttributeValue>,
                {
                    self.product_attribute_value = std::option::Option::Some(v.into());
                    self
                }

                /// Sets or clears the value of [product_attribute_value][crate::model::search_request::conversational_search_spec::user_answer::SelectedAnswer::product_attribute_value].
                pub fn set_or_clear_product_attribute_value<T>(
                    mut self,
                    v: std::option::Option<T>,
                ) -> Self
                where
                    T: std::convert::Into<crate::model::ProductAttributeValue>,
                {
                    self.product_attribute_value = v.map(|x| x.into());
                    self
                }
            }

            impl wkt::message::Message for SelectedAnswer {
                fn typename() -> &'static str {
                    "type.googleapis.com/google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec.UserAnswer.SelectedAnswer"
                }
            }

            /// This field specifies the type of user answer.
            #[derive(Clone, Debug, PartialEq)]
            #[non_exhaustive]
            pub enum Type {
                /// This field specifies the incremental input text from the user during
                /// the conversational search.
                TextAnswer(std::string::String),
                /// This field specifies the selected attributes during the
                /// conversational search. This should be a subset of
                /// [ConversationalSearchResult.suggested_answers][].
                SelectedAnswer(std::boxed::Box<crate::model::search_request::conversational_search_spec::user_answer::SelectedAnswer>),
            }
        }
    }

    /// This field specifies tile navigation related parameters.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct TileNavigationSpec {
        /// This field specifies whether the customer would like to request tile
        /// navigation.
        pub tile_navigation_requested: bool,

        /// This optional field specifies the tiles which are already clicked in
        /// client side. While the feature works without this field set, particularly
        /// for an initial query, it is highly recommended to set this field because
        /// it can improve the quality of the search response and removes possible
        /// duplicate tiles.
        ///
        /// NOTE: This field is not being used for filtering search
        /// products. Client side should also put all the applied tiles in
        /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter].
        ///
        /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
        pub applied_tiles: std::vec::Vec<crate::model::Tile>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl TileNavigationSpec {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [tile_navigation_requested][crate::model::search_request::TileNavigationSpec::tile_navigation_requested].
        pub fn set_tile_navigation_requested<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.tile_navigation_requested = v.into();
            self
        }

        /// Sets the value of [applied_tiles][crate::model::search_request::TileNavigationSpec::applied_tiles].
        pub fn set_applied_tiles<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::Tile>,
        {
            use std::iter::Iterator;
            self.applied_tiles = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for TileNavigationSpec {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchRequest.TileNavigationSpec"
        }
    }

    /// The search mode of each search request.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum SearchMode {
        /// Default value. In this case both product search and faceted search will
        /// be performed. Both
        /// [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult]
        /// and [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet]
        /// will be returned.
        ///
        /// [google.cloud.retail.v2.SearchResponse.Facet]: crate::model::search_response::Facet
        /// [google.cloud.retail.v2.SearchResponse.SearchResult]: crate::model::search_response::SearchResult
        Unspecified,
        /// Only product search will be performed. The faceted search will be
        /// disabled.
        ///
        /// Only
        /// [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult]
        /// will be returned.
        /// [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] will
        /// not be returned, even if
        /// [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs]
        /// or
        /// [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2.SearchRequest.dynamic_facet_spec]
        /// is set.
        ///
        /// [google.cloud.retail.v2.SearchRequest.dynamic_facet_spec]: crate::model::SearchRequest::dynamic_facet_spec
        /// [google.cloud.retail.v2.SearchRequest.facet_specs]: crate::model::SearchRequest::facet_specs
        /// [google.cloud.retail.v2.SearchResponse.Facet]: crate::model::search_response::Facet
        /// [google.cloud.retail.v2.SearchResponse.SearchResult]: crate::model::search_response::SearchResult
        ProductSearchOnly,
        /// Only faceted search will be performed. The product search will be
        /// disabled.
        ///
        /// When in this mode, one or both of
        /// [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs]
        /// and
        /// [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2.SearchRequest.dynamic_facet_spec]
        /// should be set. Otherwise, an INVALID_ARGUMENT error is returned. Only
        /// [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] will
        /// be returned.
        /// [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult]
        /// will not be returned.
        ///
        /// [google.cloud.retail.v2.SearchRequest.dynamic_facet_spec]: crate::model::SearchRequest::dynamic_facet_spec
        /// [google.cloud.retail.v2.SearchRequest.facet_specs]: crate::model::SearchRequest::facet_specs
        /// [google.cloud.retail.v2.SearchResponse.Facet]: crate::model::search_response::Facet
        /// [google.cloud.retail.v2.SearchResponse.SearchResult]: crate::model::search_response::SearchResult
        FacetedSearchOnly,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [SearchMode::value] or
        /// [SearchMode::name].
        UnknownValue(search_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod search_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl SearchMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::ProductSearchOnly => std::option::Option::Some(1),
                Self::FacetedSearchOnly => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("SEARCH_MODE_UNSPECIFIED"),
                Self::ProductSearchOnly => std::option::Option::Some("PRODUCT_SEARCH_ONLY"),
                Self::FacetedSearchOnly => std::option::Option::Some("FACETED_SEARCH_ONLY"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for SearchMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for SearchMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for SearchMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::ProductSearchOnly,
                2 => Self::FacetedSearchOnly,
                _ => Self::UnknownValue(search_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for SearchMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "SEARCH_MODE_UNSPECIFIED" => Self::Unspecified,
                "PRODUCT_SEARCH_ONLY" => Self::ProductSearchOnly,
                "FACETED_SEARCH_ONLY" => Self::FacetedSearchOnly,
                _ => Self::UnknownValue(search_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for SearchMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::ProductSearchOnly => serializer.serialize_i32(1),
                Self::FacetedSearchOnly => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for SearchMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<SearchMode>::new(
                ".google.cloud.retail.v2.SearchRequest.SearchMode",
            ))
        }
    }
}

/// Response message for
/// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] method.
///
/// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SearchResponse {
    /// A list of matched items. The order represents the ranking.
    pub results: std::vec::Vec<crate::model::search_response::SearchResult>,

    /// Results of facets requested by user.
    pub facets: std::vec::Vec<crate::model::search_response::Facet>,

    /// The estimated total count of matched items irrespective of pagination. The
    /// count of [results][google.cloud.retail.v2.SearchResponse.results] returned
    /// by pagination may be less than the
    /// [total_size][google.cloud.retail.v2.SearchResponse.total_size] that
    /// matches.
    ///
    /// [google.cloud.retail.v2.SearchResponse.results]: crate::model::SearchResponse::results
    /// [google.cloud.retail.v2.SearchResponse.total_size]: crate::model::SearchResponse::total_size
    pub total_size: i32,

    /// Contains the spell corrected query, if found. If the spell correction type
    /// is AUTOMATIC, then the search results are based on corrected_query.
    /// Otherwise the original query is used for search.
    pub corrected_query: std::string::String,

    /// A unique search token. This should be included in the
    /// [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting from this
    /// search, which enables accurate attribution of search model performance.
    ///
    /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
    pub attribution_token: std::string::String,

    /// A token that can be sent as
    /// [SearchRequest.page_token][google.cloud.retail.v2.SearchRequest.page_token]
    /// to retrieve the next page. If this field is omitted, there are no
    /// subsequent pages.
    ///
    /// [google.cloud.retail.v2.SearchRequest.page_token]: crate::model::SearchRequest::page_token
    pub next_page_token: std::string::String,

    /// Query expansion information for the returned results.
    pub query_expansion_info:
        std::option::Option<crate::model::search_response::QueryExpansionInfo>,

    /// The URI of a customer-defined redirect page. If redirect action is
    /// triggered, no search is performed, and only
    /// [redirect_uri][google.cloud.retail.v2.SearchResponse.redirect_uri] and
    /// [attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token]
    /// are set in the response.
    ///
    /// [google.cloud.retail.v2.SearchResponse.attribution_token]: crate::model::SearchResponse::attribution_token
    /// [google.cloud.retail.v2.SearchResponse.redirect_uri]: crate::model::SearchResponse::redirect_uri
    pub redirect_uri: std::string::String,

    /// The fully qualified resource name of applied
    /// [controls](https://cloud.google.com/retail/docs/serving-control-rules).
    pub applied_controls: std::vec::Vec<std::string::String>,

    /// Metadata for pin controls which were applicable to the request.
    /// This contains two map fields, one for all matched pins and one for pins
    /// which were matched but not applied.
    ///
    /// The two maps are keyed by pin position, and the values are the product ids
    /// which were matched to that pin.
    pub pin_control_metadata: std::option::Option<crate::model::PinControlMetadata>,

    /// The invalid
    /// [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]
    /// that are not applied during serving.
    ///
    /// [google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]: crate::model::search_request::BoostSpec::condition_boost_specs
    pub invalid_condition_boost_specs:
        std::vec::Vec<crate::model::search_request::boost_spec::ConditionBoostSpec>,

    /// Metadata related to A/B testing experiment associated with this
    /// response. Only exists when an experiment is triggered.
    pub experiment_info: std::vec::Vec<crate::model::ExperimentInfo>,

    /// This field specifies all related information that is needed on client
    /// side for UI rendering of conversational retail search.
    pub conversational_search_result:
        std::option::Option<crate::model::search_response::ConversationalSearchResult>,

    /// This field specifies all related information for tile navigation that will
    /// be used in client side.
    pub tile_navigation_result:
        std::option::Option<crate::model::search_response::TileNavigationResult>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SearchResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [results][crate::model::SearchResponse::results].
    pub fn set_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::search_response::SearchResult>,
    {
        use std::iter::Iterator;
        self.results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [facets][crate::model::SearchResponse::facets].
    pub fn set_facets<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::search_response::Facet>,
    {
        use std::iter::Iterator;
        self.facets = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [total_size][crate::model::SearchResponse::total_size].
    pub fn set_total_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.total_size = v.into();
        self
    }

    /// Sets the value of [corrected_query][crate::model::SearchResponse::corrected_query].
    pub fn set_corrected_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.corrected_query = v.into();
        self
    }

    /// Sets the value of [attribution_token][crate::model::SearchResponse::attribution_token].
    pub fn set_attribution_token<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attribution_token = v.into();
        self
    }

    /// Sets the value of [next_page_token][crate::model::SearchResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }

    /// Sets the value of [query_expansion_info][crate::model::SearchResponse::query_expansion_info].
    pub fn set_query_expansion_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_response::QueryExpansionInfo>,
    {
        self.query_expansion_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [query_expansion_info][crate::model::SearchResponse::query_expansion_info].
    pub fn set_or_clear_query_expansion_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_response::QueryExpansionInfo>,
    {
        self.query_expansion_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [redirect_uri][crate::model::SearchResponse::redirect_uri].
    pub fn set_redirect_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.redirect_uri = v.into();
        self
    }

    /// Sets the value of [applied_controls][crate::model::SearchResponse::applied_controls].
    pub fn set_applied_controls<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.applied_controls = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [pin_control_metadata][crate::model::SearchResponse::pin_control_metadata].
    pub fn set_pin_control_metadata<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::PinControlMetadata>,
    {
        self.pin_control_metadata = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [pin_control_metadata][crate::model::SearchResponse::pin_control_metadata].
    pub fn set_or_clear_pin_control_metadata<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::PinControlMetadata>,
    {
        self.pin_control_metadata = v.map(|x| x.into());
        self
    }

    /// Sets the value of [invalid_condition_boost_specs][crate::model::SearchResponse::invalid_condition_boost_specs].
    pub fn set_invalid_condition_boost_specs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::search_request::boost_spec::ConditionBoostSpec>,
    {
        use std::iter::Iterator;
        self.invalid_condition_boost_specs = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [experiment_info][crate::model::SearchResponse::experiment_info].
    pub fn set_experiment_info<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ExperimentInfo>,
    {
        use std::iter::Iterator;
        self.experiment_info = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [conversational_search_result][crate::model::SearchResponse::conversational_search_result].
    pub fn set_conversational_search_result<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_response::ConversationalSearchResult>,
    {
        self.conversational_search_result = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [conversational_search_result][crate::model::SearchResponse::conversational_search_result].
    pub fn set_or_clear_conversational_search_result<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_response::ConversationalSearchResult>,
    {
        self.conversational_search_result = v.map(|x| x.into());
        self
    }

    /// Sets the value of [tile_navigation_result][crate::model::SearchResponse::tile_navigation_result].
    pub fn set_tile_navigation_result<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_response::TileNavigationResult>,
    {
        self.tile_navigation_result = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [tile_navigation_result][crate::model::SearchResponse::tile_navigation_result].
    pub fn set_or_clear_tile_navigation_result<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_response::TileNavigationResult>,
    {
        self.tile_navigation_result = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for SearchResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.SearchResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for SearchResponse {
    type PageItem = crate::model::search_response::SearchResult;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.results
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// Defines additional types related to [SearchResponse].
pub mod search_response {
    #[allow(unused_imports)]
    use super::*;

    /// Represents the search results.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct SearchResult {
        /// [Product.id][google.cloud.retail.v2.Product.id] of the searched
        /// [Product][google.cloud.retail.v2.Product].
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
        pub id: std::string::String,

        /// The product data snippet in the search response. Only
        /// [Product.name][google.cloud.retail.v2.Product.name] is guaranteed to be
        /// populated.
        ///
        /// [Product.variants][google.cloud.retail.v2.Product.variants] contains the
        /// product variants that match the search query. If there are multiple
        /// product variants matching the query, top 5 most relevant product variants
        /// are returned and ordered by relevancy.
        ///
        /// If relevancy can be deternmined, use
        /// [matching_variant_fields][google.cloud.retail.v2.SearchResponse.SearchResult.matching_variant_fields]
        /// to look up matched product variants fields. If relevancy cannot be
        /// determined, e.g. when searching "shoe" all products in a shoe product can
        /// be a match, 5 product variants are returned but order is meaningless.
        ///
        /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
        /// [google.cloud.retail.v2.Product.variants]: crate::model::Product::variants
        /// [google.cloud.retail.v2.SearchResponse.SearchResult.matching_variant_fields]: crate::model::search_response::SearchResult::matching_variant_fields
        pub product: std::option::Option<crate::model::Product>,

        /// The count of matched
        /// [variant][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product]s.
        ///
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        pub matching_variant_count: i32,

        /// If a [variant][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product] matches the search query, this
        /// map indicates which [Product][google.cloud.retail.v2.Product] fields are
        /// matched. The key is the
        /// [Product.name][google.cloud.retail.v2.Product.name], the value is a field
        /// mask of the matched [Product][google.cloud.retail.v2.Product] fields. If
        /// matched attributes cannot be determined, this map will be empty.
        ///
        /// For example, a key "sku1" with field mask
        /// "products.color_info" indicates there is a match between
        /// "sku1" [ColorInfo][google.cloud.retail.v2.ColorInfo] and the query.
        ///
        /// [google.cloud.retail.v2.ColorInfo]: crate::model::ColorInfo
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        /// [google.cloud.retail.v2.Product.name]: crate::model::Product::name
        pub matching_variant_fields: std::collections::HashMap<std::string::String, wkt::FieldMask>,

        /// The rollup matching
        /// [variant][google.cloud.retail.v2.Product.Type.VARIANT]
        /// [Product][google.cloud.retail.v2.Product] attributes. The key is one of
        /// the
        /// [SearchRequest.variant_rollup_keys][google.cloud.retail.v2.SearchRequest.variant_rollup_keys].
        /// The values are the merged and de-duplicated
        /// [Product][google.cloud.retail.v2.Product] attributes. Notice that the
        /// rollup values are respect filter. For example, when filtering by
        /// "colorFamilies:ANY(\"red\")" and rollup "colorFamilies", only "red" is
        /// returned.
        ///
        /// For textual and numerical attributes, the rollup values is a list of
        /// string or double values with type
        /// [google.protobuf.ListValue][google.protobuf.ListValue]. For example, if
        /// there are two variants with colors "red" and "blue", the rollup values
        /// are
        ///
        /// ```norust
        /// { key: "colorFamilies"
        ///   value {
        ///     list_value {
        ///       values { string_value: "red" }
        ///       values { string_value: "blue" }
        ///      }
        ///   }
        /// }
        /// ```
        ///
        /// For [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], the rollup
        /// values is a double value with type
        /// [google.protobuf.Value][google.protobuf.Value]. For example,
        /// `{key: "pickupInStore.store1" value { number_value: 10 }}` means a there
        /// are 10 variants in this product are available in the store "store1".
        ///
        /// [google.cloud.retail.v2.FulfillmentInfo]: crate::model::FulfillmentInfo
        /// [google.cloud.retail.v2.Product]: crate::model::Product
        /// [google.cloud.retail.v2.Product.Type.VARIANT]: crate::model::product::Type::Variant
        /// [google.cloud.retail.v2.SearchRequest.variant_rollup_keys]: crate::model::SearchRequest::variant_rollup_keys
        /// [google.protobuf.ListValue]: wkt::ListValue
        /// [google.protobuf.Value]: wkt::Value
        pub variant_rollup_values: std::collections::HashMap<std::string::String, wkt::Value>,

        /// Specifies previous events related to this product for this user based on
        /// [UserEvent][google.cloud.retail.v2.UserEvent] with same
        /// [SearchRequest.visitor_id][google.cloud.retail.v2.SearchRequest.visitor_id]
        /// or [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id].
        ///
        /// This is set only when
        /// [SearchRequest.PersonalizationSpec.mode][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.mode]
        /// is
        /// [SearchRequest.PersonalizationSpec.Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO].
        ///
        /// Possible values:
        ///
        /// * `purchased`: Indicates that this product has been purchased before.
        ///
        /// [google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]: crate::model::search_request::personalization_spec::Mode::Auto
        /// [google.cloud.retail.v2.SearchRequest.PersonalizationSpec.mode]: crate::model::search_request::PersonalizationSpec::mode
        /// [google.cloud.retail.v2.SearchRequest.visitor_id]: crate::model::SearchRequest::visitor_id
        /// [google.cloud.retail.v2.UserEvent]: crate::model::UserEvent
        /// [google.cloud.retail.v2.UserInfo.user_id]: crate::model::UserInfo::user_id
        pub personal_labels: std::vec::Vec<std::string::String>,

        /// Google provided available scores.
        pub model_scores: std::collections::HashMap<std::string::String, crate::model::DoubleList>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl SearchResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [id][crate::model::search_response::SearchResult::id].
        pub fn set_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.id = v.into();
            self
        }

        /// Sets the value of [product][crate::model::search_response::SearchResult::product].
        pub fn set_product<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Product>,
        {
            self.product = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [product][crate::model::search_response::SearchResult::product].
        pub fn set_or_clear_product<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Product>,
        {
            self.product = v.map(|x| x.into());
            self
        }

        /// Sets the value of [matching_variant_count][crate::model::search_response::SearchResult::matching_variant_count].
        pub fn set_matching_variant_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.matching_variant_count = v.into();
            self
        }

        /// Sets the value of [matching_variant_fields][crate::model::search_response::SearchResult::matching_variant_fields].
        pub fn set_matching_variant_fields<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<wkt::FieldMask>,
        {
            use std::iter::Iterator;
            self.matching_variant_fields =
                v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }

        /// Sets the value of [variant_rollup_values][crate::model::search_response::SearchResult::variant_rollup_values].
        pub fn set_variant_rollup_values<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<wkt::Value>,
        {
            use std::iter::Iterator;
            self.variant_rollup_values = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }

        /// Sets the value of [personal_labels][crate::model::search_response::SearchResult::personal_labels].
        pub fn set_personal_labels<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.personal_labels = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [model_scores][crate::model::search_response::SearchResult::model_scores].
        pub fn set_model_scores<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<crate::model::DoubleList>,
        {
            use std::iter::Iterator;
            self.model_scores = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }
    }

    impl wkt::message::Message for SearchResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchResponse.SearchResult"
        }
    }

    /// A facet result.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Facet {
        /// The key for this facet. E.g., "colorFamilies" or "price" or
        /// "attributes.attr1".
        pub key: std::string::String,

        /// The facet values for this field.
        pub values: std::vec::Vec<crate::model::search_response::facet::FacetValue>,

        /// Whether the facet is dynamically generated.
        pub dynamic_facet: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Facet {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [key][crate::model::search_response::Facet::key].
        pub fn set_key<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.key = v.into();
            self
        }

        /// Sets the value of [values][crate::model::search_response::Facet::values].
        pub fn set_values<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::search_response::facet::FacetValue>,
        {
            use std::iter::Iterator;
            self.values = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [dynamic_facet][crate::model::search_response::Facet::dynamic_facet].
        pub fn set_dynamic_facet<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.dynamic_facet = v.into();
            self
        }
    }

    impl wkt::message::Message for Facet {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchResponse.Facet"
        }
    }

    /// Defines additional types related to [Facet].
    pub mod facet {
        #[allow(unused_imports)]
        use super::*;

        /// A facet value which contains value names and their count.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct FacetValue {
            /// Number of items that have this facet value.
            pub count: i64,

            /// The minimum value in the
            /// [FacetValue.interval][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval].
            /// Only supported on numerical facets and returned if
            /// [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max]
            /// is true.
            ///
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max]: crate::model::search_request::facet_spec::FacetKey::return_min_max
            /// [google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval]: crate::model::search_response::facet::FacetValue::facet_value
            pub min_value: f64,

            /// The maximum value in the
            /// [FacetValue.interval][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval].
            /// Only supported on numerical facets and returned if
            /// [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max]
            /// is true.
            ///
            /// [google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max]: crate::model::search_request::facet_spec::FacetKey::return_min_max
            /// [google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval]: crate::model::search_response::facet::FacetValue::facet_value
            pub max_value: f64,

            /// A facet value which contains values.
            pub facet_value:
                std::option::Option<crate::model::search_response::facet::facet_value::FacetValue>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl FacetValue {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [count][crate::model::search_response::facet::FacetValue::count].
            pub fn set_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
                self.count = v.into();
                self
            }

            /// Sets the value of [min_value][crate::model::search_response::facet::FacetValue::min_value].
            pub fn set_min_value<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
                self.min_value = v.into();
                self
            }

            /// Sets the value of [max_value][crate::model::search_response::facet::FacetValue::max_value].
            pub fn set_max_value<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
                self.max_value = v.into();
                self
            }

            /// Sets the value of [facet_value][crate::model::search_response::facet::FacetValue::facet_value].
            ///
            /// Note that all the setters affecting `facet_value` are mutually
            /// exclusive.
            pub fn set_facet_value<
                T: std::convert::Into<
                        std::option::Option<
                            crate::model::search_response::facet::facet_value::FacetValue,
                        >,
                    >,
            >(
                mut self,
                v: T,
            ) -> Self {
                self.facet_value = v.into();
                self
            }

            /// The value of [facet_value][crate::model::search_response::facet::FacetValue::facet_value]
            /// if it holds a `Value`, `None` if the field is not set or
            /// holds a different branch.
            pub fn value(&self) -> std::option::Option<&std::string::String> {
                #[allow(unreachable_patterns)]
                self.facet_value.as_ref().and_then(|v| match v {
                    crate::model::search_response::facet::facet_value::FacetValue::Value(v) => {
                        std::option::Option::Some(v)
                    }
                    _ => std::option::Option::None,
                })
            }

            /// Sets the value of [facet_value][crate::model::search_response::facet::FacetValue::facet_value]
            /// to hold a `Value`.
            ///
            /// Note that all the setters affecting `facet_value` are
            /// mutually exclusive.
            pub fn set_value<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
                self.facet_value = std::option::Option::Some(
                    crate::model::search_response::facet::facet_value::FacetValue::Value(v.into()),
                );
                self
            }

            /// The value of [facet_value][crate::model::search_response::facet::FacetValue::facet_value]
            /// if it holds a `Interval`, `None` if the field is not set or
            /// holds a different branch.
            pub fn interval(
                &self,
            ) -> std::option::Option<&std::boxed::Box<crate::model::Interval>> {
                #[allow(unreachable_patterns)]
                self.facet_value.as_ref().and_then(|v| match v {
                    crate::model::search_response::facet::facet_value::FacetValue::Interval(v) => {
                        std::option::Option::Some(v)
                    }
                    _ => std::option::Option::None,
                })
            }

            /// Sets the value of [facet_value][crate::model::search_response::facet::FacetValue::facet_value]
            /// to hold a `Interval`.
            ///
            /// Note that all the setters affecting `facet_value` are
            /// mutually exclusive.
            pub fn set_interval<T: std::convert::Into<std::boxed::Box<crate::model::Interval>>>(
                mut self,
                v: T,
            ) -> Self {
                self.facet_value = std::option::Option::Some(
                    crate::model::search_response::facet::facet_value::FacetValue::Interval(
                        v.into(),
                    ),
                );
                self
            }
        }

        impl wkt::message::Message for FacetValue {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.SearchResponse.Facet.FacetValue"
            }
        }

        /// Defines additional types related to [FacetValue].
        pub mod facet_value {
            #[allow(unused_imports)]
            use super::*;

            /// A facet value which contains values.
            #[derive(Clone, Debug, PartialEq)]
            #[non_exhaustive]
            pub enum FacetValue {
                /// Text value of a facet, such as "Black" for facet "colorFamilies".
                Value(std::string::String),
                /// Interval value for a facet, such as [10, 20) for facet "price".
                Interval(std::boxed::Box<crate::model::Interval>),
            }
        }
    }

    /// Information describing query expansion including whether expansion has
    /// occurred.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct QueryExpansionInfo {
        /// Bool describing whether query expansion has occurred.
        pub expanded_query: bool,

        /// Number of pinned results. This field will only be set when expansion
        /// happens and
        /// [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.pin_unexpanded_results]
        /// is set to true.
        ///
        /// [google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.pin_unexpanded_results]: crate::model::search_request::QueryExpansionSpec::pin_unexpanded_results
        pub pinned_result_count: i64,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl QueryExpansionInfo {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [expanded_query][crate::model::search_response::QueryExpansionInfo::expanded_query].
        pub fn set_expanded_query<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.expanded_query = v.into();
            self
        }

        /// Sets the value of [pinned_result_count][crate::model::search_response::QueryExpansionInfo::pinned_result_count].
        pub fn set_pinned_result_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
            self.pinned_result_count = v.into();
            self
        }
    }

    impl wkt::message::Message for QueryExpansionInfo {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchResponse.QueryExpansionInfo"
        }
    }

    /// This field specifies all related information that is needed on client
    /// side for UI rendering of conversational retail search.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ConversationalSearchResult {
        /// Conversation UUID. This field will be stored in client side storage to
        /// maintain the conversation session with server and will be used for next
        /// search request's
        /// [SearchRequest.ConversationalSearchSpec.conversation_id][google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec.conversation_id]
        /// to restore conversation state in server.
        ///
        /// [google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec.conversation_id]: crate::model::search_request::ConversationalSearchSpec::conversation_id
        pub conversation_id: std::string::String,

        /// The current refined query for the conversational search. This field
        /// will be used in customer UI that the query in the search bar should be
        /// replaced with the refined query. For example, if
        /// [SearchRequest.query][google.cloud.retail.v2.SearchRequest.query] is
        /// `dress` and next
        /// [SearchRequest.ConversationalSearchSpec.UserAnswer.text_answer][google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec.UserAnswer.text_answer]
        /// is `red color`, which does not match any product attribute value filters,
        /// the refined query will be `dress, red color`.
        ///
        /// [google.cloud.retail.v2.SearchRequest.ConversationalSearchSpec.UserAnswer.text_answer]: crate::model::search_request::conversational_search_spec::UserAnswer::type
        /// [google.cloud.retail.v2.SearchRequest.query]: crate::model::SearchRequest::query
        pub refined_query: std::string::String,

        /// This field is deprecated but will be kept for backward compatibility.
        /// There is expected to have only one additional filter and the value will
        /// be the same to the same as field `additional_filter`.
        #[deprecated]
        pub additional_filters: std::vec::Vec<
            crate::model::search_response::conversational_search_result::AdditionalFilter,
        >,

        /// The follow-up question. e.g., `What is the color?`
        pub followup_question: std::string::String,

        /// The answer options provided to client for the follow-up question.
        pub suggested_answers: std::vec::Vec<
            crate::model::search_response::conversational_search_result::SuggestedAnswer,
        >,

        /// This is the incremental additional filters implied from the current
        /// user answer. User should add the suggested addition filters to the
        /// previous
        /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter],  and
        /// use the merged filter in the follow up search request.
        ///
        /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
        pub additional_filter: std::option::Option<
            crate::model::search_response::conversational_search_result::AdditionalFilter,
        >,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ConversationalSearchResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [conversation_id][crate::model::search_response::ConversationalSearchResult::conversation_id].
        pub fn set_conversation_id<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.conversation_id = v.into();
            self
        }

        /// Sets the value of [refined_query][crate::model::search_response::ConversationalSearchResult::refined_query].
        pub fn set_refined_query<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.refined_query = v.into();
            self
        }

        /// Sets the value of [additional_filters][crate::model::search_response::ConversationalSearchResult::additional_filters].
        #[deprecated]
        pub fn set_additional_filters<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<
                    crate::model::search_response::conversational_search_result::AdditionalFilter,
                >,
        {
            use std::iter::Iterator;
            self.additional_filters = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [followup_question][crate::model::search_response::ConversationalSearchResult::followup_question].
        pub fn set_followup_question<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.followup_question = v.into();
            self
        }

        /// Sets the value of [suggested_answers][crate::model::search_response::ConversationalSearchResult::suggested_answers].
        pub fn set_suggested_answers<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<
                    crate::model::search_response::conversational_search_result::SuggestedAnswer,
                >,
        {
            use std::iter::Iterator;
            self.suggested_answers = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [additional_filter][crate::model::search_response::ConversationalSearchResult::additional_filter].
        pub fn set_additional_filter<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<
                    crate::model::search_response::conversational_search_result::AdditionalFilter,
                >,
        {
            self.additional_filter = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [additional_filter][crate::model::search_response::ConversationalSearchResult::additional_filter].
        pub fn set_or_clear_additional_filter<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<
                    crate::model::search_response::conversational_search_result::AdditionalFilter,
                >,
        {
            self.additional_filter = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for ConversationalSearchResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchResponse.ConversationalSearchResult"
        }
    }

    /// Defines additional types related to [ConversationalSearchResult].
    pub mod conversational_search_result {
        #[allow(unused_imports)]
        use super::*;

        /// Suggested answers to the follow-up question.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct SuggestedAnswer {
            /// Product attribute value, including an attribute key and an
            /// attribute value. Other types can be added here in the future.
            pub product_attribute_value: std::option::Option<crate::model::ProductAttributeValue>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl SuggestedAnswer {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [product_attribute_value][crate::model::search_response::conversational_search_result::SuggestedAnswer::product_attribute_value].
            pub fn set_product_attribute_value<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [product_attribute_value][crate::model::search_response::conversational_search_result::SuggestedAnswer::product_attribute_value].
            pub fn set_or_clear_product_attribute_value<T>(
                mut self,
                v: std::option::Option<T>,
            ) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for SuggestedAnswer {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.SearchResponse.ConversationalSearchResult.SuggestedAnswer"
            }
        }

        /// Additional filter that client side need to apply.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct AdditionalFilter {
            /// Product attribute value, including an attribute key and an
            /// attribute value. Other types can be added here in the future.
            pub product_attribute_value: std::option::Option<crate::model::ProductAttributeValue>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl AdditionalFilter {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [product_attribute_value][crate::model::search_response::conversational_search_result::AdditionalFilter::product_attribute_value].
            pub fn set_product_attribute_value<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [product_attribute_value][crate::model::search_response::conversational_search_result::AdditionalFilter::product_attribute_value].
            pub fn set_or_clear_product_attribute_value<T>(
                mut self,
                v: std::option::Option<T>,
            ) -> Self
            where
                T: std::convert::Into<crate::model::ProductAttributeValue>,
            {
                self.product_attribute_value = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for AdditionalFilter {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.retail.v2.SearchResponse.ConversationalSearchResult.AdditionalFilter"
            }
        }
    }

    /// This field specifies all related information for tile navigation that will
    /// be used in client side.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct TileNavigationResult {
        /// The current tiles that are used for tile navigation, sorted by
        /// engagement.
        pub tiles: std::vec::Vec<crate::model::Tile>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl TileNavigationResult {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [tiles][crate::model::search_response::TileNavigationResult::tiles].
        pub fn set_tiles<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::Tile>,
        {
            use std::iter::Iterator;
            self.tiles = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for TileNavigationResult {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.SearchResponse.TileNavigationResult"
        }
    }
}

/// Metadata for active A/B testing experiment.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExperimentInfo {
    /// The fully qualified resource name of the experiment that provides the
    /// serving config under test, should an active experiment exist. For example:
    /// `projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`
    pub experiment: std::string::String,

    /// Information associated with the specific experiment entity being recorded.
    pub experiment_metadata: std::option::Option<crate::model::experiment_info::ExperimentMetadata>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExperimentInfo {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [experiment][crate::model::ExperimentInfo::experiment].
    pub fn set_experiment<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.experiment = v.into();
        self
    }

    /// Sets the value of [experiment_metadata][crate::model::ExperimentInfo::experiment_metadata].
    ///
    /// Note that all the setters affecting `experiment_metadata` are mutually
    /// exclusive.
    pub fn set_experiment_metadata<
        T: std::convert::Into<std::option::Option<crate::model::experiment_info::ExperimentMetadata>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.experiment_metadata = v.into();
        self
    }

    /// The value of [experiment_metadata][crate::model::ExperimentInfo::experiment_metadata]
    /// if it holds a `ServingConfigExperiment`, `None` if the field is not set or
    /// holds a different branch.
    pub fn serving_config_experiment(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::experiment_info::ServingConfigExperiment>>
    {
        #[allow(unreachable_patterns)]
        self.experiment_metadata.as_ref().and_then(|v| match v {
            crate::model::experiment_info::ExperimentMetadata::ServingConfigExperiment(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [experiment_metadata][crate::model::ExperimentInfo::experiment_metadata]
    /// to hold a `ServingConfigExperiment`.
    ///
    /// Note that all the setters affecting `experiment_metadata` are
    /// mutually exclusive.
    pub fn set_serving_config_experiment<
        T: std::convert::Into<std::boxed::Box<crate::model::experiment_info::ServingConfigExperiment>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.experiment_metadata = std::option::Option::Some(
            crate::model::experiment_info::ExperimentMetadata::ServingConfigExperiment(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ExperimentInfo {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ExperimentInfo"
    }
}

/// Defines additional types related to [ExperimentInfo].
pub mod experiment_info {
    #[allow(unused_imports)]
    use super::*;

    /// Metadata for active serving config A/B tests.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ServingConfigExperiment {
        /// The fully qualified resource name of the original
        /// [SearchRequest.placement][google.cloud.retail.v2.SearchRequest.placement]
        /// in the search request prior to reassignment by experiment API. For
        /// example: `projects/*/locations/*/catalogs/*/servingConfigs/*`.
        ///
        /// [google.cloud.retail.v2.SearchRequest.placement]: crate::model::SearchRequest::placement
        pub original_serving_config: std::string::String,

        /// The fully qualified resource name of the serving config
        /// `Experiment.VariantArm.serving_config_id` responsible for generating
        /// the search response. For example:
        /// `projects/*/locations/*/catalogs/*/servingConfigs/*`.
        pub experiment_serving_config: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ServingConfigExperiment {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [original_serving_config][crate::model::experiment_info::ServingConfigExperiment::original_serving_config].
        pub fn set_original_serving_config<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.original_serving_config = v.into();
            self
        }

        /// Sets the value of [experiment_serving_config][crate::model::experiment_info::ServingConfigExperiment::experiment_serving_config].
        pub fn set_experiment_serving_config<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.experiment_serving_config = v.into();
            self
        }
    }

    impl wkt::message::Message for ServingConfigExperiment {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.retail.v2.ExperimentInfo.ServingConfigExperiment"
        }
    }

    /// Information associated with the specific experiment entity being recorded.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ExperimentMetadata {
        /// A/B test between existing Cloud Retail Search
        /// [ServingConfig][google.cloud.retail.v2.ServingConfig]s.
        ///
        /// [google.cloud.retail.v2.ServingConfig]: crate::model::ServingConfig
        ServingConfigExperiment(
            std::boxed::Box<crate::model::experiment_info::ServingConfigExperiment>,
        ),
    }
}

/// Configures metadata that is used to generate serving time results (e.g.
/// search results or recommendation predictions).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ServingConfig {
    /// Immutable. Fully qualified name
    /// `projects/*/locations/global/catalogs/*/servingConfig/*`
    pub name: std::string::String,

    /// Required. The human readable serving config display name. Used in Retail
    /// UI.
    ///
    /// This field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    pub display_name: std::string::String,

    /// The id of the model in the same [Catalog][google.cloud.retail.v2.Catalog]
    /// to use at serving time. Currently only RecommendationModels are supported:
    /// <https://cloud.google.com/retail/recommendations-ai/docs/create-models>
    /// Can be changed but only to a compatible model (e.g.
    /// others-you-may-like CTR to others-you-may-like CVR).
    ///
    /// Required when
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION]: crate::model::SolutionType::Recommendation
    pub model_id: std::string::String,

    /// How much price ranking we want in serving results.
    /// Price reranking causes product items with a similar
    /// recommendation probability to be ordered by price, with the
    /// highest-priced items first. This setting could result in a decrease in
    /// click-through and conversion rates.
    /// Allowed values are:
    ///
    /// * `no-price-reranking`
    /// * `low-price-reranking`
    /// * `medium-price-reranking`
    /// * `high-price-reranking`
    ///
    /// If not specified, we choose default based on model type. Default value:
    /// `no-price-reranking`.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION]: crate::model::SolutionType::Recommendation
    pub price_reranking_level: std::string::String,

    /// Facet specifications for faceted search. If empty, no facets are returned.
    /// The ids refer to the ids of [Control][google.cloud.retail.v2.Control]
    /// resources with only the Facet control set. These controls are assumed to be
    /// in the same [Catalog][google.cloud.retail.v2.Catalog] as the
    /// [ServingConfig][google.cloud.retail.v2.ServingConfig].
    /// A maximum of 100 values are allowed. Otherwise, an INVALID_ARGUMENT error
    /// is returned.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.Catalog]: crate::model::Catalog
    /// [google.cloud.retail.v2.Control]: crate::model::Control
    /// [google.cloud.retail.v2.ServingConfig]: crate::model::ServingConfig
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub facet_control_ids: std::vec::Vec<std::string::String>,

    /// The specification for dynamically generated facets. Notice that only
    /// textual facets can be dynamically generated.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub dynamic_facet_spec: std::option::Option<crate::model::search_request::DynamicFacetSpec>,

    /// Condition boost specifications. If a product matches multiple conditions
    /// in the specifications, boost scores from these specifications are all
    /// applied and combined in a non-linear way. Maximum number of
    /// specifications is 100.
    ///
    /// Notice that if both
    /// [ServingConfig.boost_control_ids][google.cloud.retail.v2.ServingConfig.boost_control_ids]
    /// and
    /// [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec]
    /// are set, the boost conditions from both places are evaluated. If a search
    /// request matches multiple boost conditions, the final boost score is equal
    /// to the sum of the boost scores from all matched boost conditions.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.SearchRequest.boost_spec]: crate::model::SearchRequest::boost_spec
    /// [google.cloud.retail.v2.ServingConfig.boost_control_ids]: crate::model::ServingConfig::boost_control_ids
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub boost_control_ids: std::vec::Vec<std::string::String>,

    /// Condition filter specifications. If a product matches multiple conditions
    /// in the specifications, filters from these specifications are all
    /// applied and combined via the AND operator. Maximum number of
    /// specifications is 100.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub filter_control_ids: std::vec::Vec<std::string::String>,

    /// Condition redirect specifications. Only the first triggered redirect action
    /// is applied, even if multiple apply. Maximum number of specifications is
    /// 1000.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub redirect_control_ids: std::vec::Vec<std::string::String>,

    /// Condition synonyms specifications. If multiple syonyms conditions match,
    /// all matching synonyms control in the list will execute. Order of controls
    /// in the list will not matter. Maximum number of specifications is
    /// 100.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub twoway_synonyms_control_ids: std::vec::Vec<std::string::String>,

    /// Condition oneway synonyms specifications. If multiple oneway synonyms
    /// conditions match, all matching oneway synonyms controls in the list will
    /// execute. Order of controls in the list will not matter. Maximum number of
    /// specifications is 100.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub oneway_synonyms_control_ids: std::vec::Vec<std::string::String>,

    /// Condition do not associate specifications. If multiple do not associate
    /// conditions match, all matching do not associate controls in the list will
    /// execute.
    ///
    /// - Order does not matter.
    /// - Maximum number of specifications is 100.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub do_not_associate_control_ids: std::vec::Vec<std::string::String>,

    /// Condition replacement specifications.
    ///
    /// - Applied according to the order in the list.
    /// - A previously replaced term can not be re-replaced.
    /// - Maximum number of specifications is 100.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub replacement_control_ids: std::vec::Vec<std::string::String>,

    /// Condition ignore specifications. If multiple ignore
    /// conditions match, all matching ignore controls in the list will
    /// execute.
    ///
    /// - Order does not matter.
    /// - Maximum number of specifications is 100.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub ignore_control_ids: std::vec::Vec<std::string::String>,

    /// How much diversity to use in recommendation model results e.g.
    /// `medium-diversity` or `high-diversity`. Currently supported values:
    ///
    /// * `no-diversity`
    /// * `low-diversity`
    /// * `medium-diversity`
    /// * `high-diversity`
    /// * `auto-diversity`
    ///
    /// If not specified, we choose default based on recommendation model
    /// type. Default value: `no-diversity`.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION]: crate::model::SolutionType::Recommendation
    pub diversity_level: std::string::String,

    /// What kind of diversity to use - data driven or rule based. If unset, the
    /// server behavior defaults to
    /// [RULE_BASED_DIVERSITY][google.cloud.retail.v2.ServingConfig.DiversityType.RULE_BASED_DIVERSITY].
    ///
    /// [google.cloud.retail.v2.ServingConfig.DiversityType.RULE_BASED_DIVERSITY]: crate::model::serving_config::DiversityType::RuleBasedDiversity
    pub diversity_type: crate::model::serving_config::DiversityType,

    /// Whether to add additional category filters on the `similar-items` model.
    /// If not specified, we enable it by default.
    /// Allowed values are:
    ///
    /// * `no-category-match`: No additional filtering of original results from
    ///   the model and the customer's filters.
    /// * `relaxed-category-match`: Only keep results with categories that match
    ///   at least one item categories in the PredictRequests's context item.
    ///   * If customer also sends filters in the PredictRequest, then the results
    ///     will satisfy both conditions (user given and category match).
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
    ///
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION]: crate::model::SolutionType::Recommendation
    pub enable_category_filter_level: std::string::String,

    /// When the flag is enabled, the products in the denylist will not be filtered
    /// out in the recommendation filtering results.
    pub ignore_recs_denylist: bool,

    /// The specification for personalization spec.
    ///
    /// Can only be set if
    /// [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
    /// [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
    ///
    /// Notice that if both
    /// [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec]
    /// and
    /// [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
    /// are set.
    /// [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
    /// will override
    /// [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec].
    ///
    /// [google.cloud.retail.v2.SearchRequest.personalization_spec]: crate::model::SearchRequest::personalization_spec
    /// [google.cloud.retail.v2.ServingConfig.personalization_spec]: crate::model::ServingConfig::personalization_spec
    /// [google.cloud.retail.v2.ServingConfig.solution_types]: crate::model::ServingConfig::solution_types
    /// [google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]: crate::model::SolutionType::Search
    pub personalization_spec:
        std::option::Option<crate::model::search_request::PersonalizationSpec>,

    /// Required. Immutable. Specifies the solution types that a serving config can
    /// be associated with. Currently we support setting only one type of solution.
    pub solution_types: std::vec::Vec<crate::model::SolutionType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ServingConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::ServingConfig::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [display_name][crate::model::ServingConfig::display_name].
    pub fn set_display_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.display_name = v.into();
        self
    }

    /// Sets the value of [model_id][crate::model::ServingConfig::model_id].
    pub fn set_model_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.model_id = v.into();
        self
    }

    /// Sets the value of [price_reranking_level][crate::model::ServingConfig::price_reranking_level].
    pub fn set_price_reranking_level<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.price_reranking_level = v.into();
        self
    }

    /// Sets the value of [facet_control_ids][crate::model::ServingConfig::facet_control_ids].
    pub fn set_facet_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.facet_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [dynamic_facet_spec][crate::model::ServingConfig::dynamic_facet_spec].
    pub fn set_dynamic_facet_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::DynamicFacetSpec>,
    {
        self.dynamic_facet_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [dynamic_facet_spec][crate::model::ServingConfig::dynamic_facet_spec].
    pub fn set_or_clear_dynamic_facet_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::DynamicFacetSpec>,
    {
        self.dynamic_facet_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [boost_control_ids][crate::model::ServingConfig::boost_control_ids].
    pub fn set_boost_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.boost_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [filter_control_ids][crate::model::ServingConfig::filter_control_ids].
    pub fn set_filter_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.filter_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [redirect_control_ids][crate::model::ServingConfig::redirect_control_ids].
    pub fn set_redirect_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.redirect_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [twoway_synonyms_control_ids][crate::model::ServingConfig::twoway_synonyms_control_ids].
    pub fn set_twoway_synonyms_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.twoway_synonyms_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [oneway_synonyms_control_ids][crate::model::ServingConfig::oneway_synonyms_control_ids].
    pub fn set_oneway_synonyms_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.oneway_synonyms_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [do_not_associate_control_ids][crate::model::ServingConfig::do_not_associate_control_ids].
    pub fn set_do_not_associate_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.do_not_associate_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [replacement_control_ids][crate::model::ServingConfig::replacement_control_ids].
    pub fn set_replacement_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.replacement_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [ignore_control_ids][crate::model::ServingConfig::ignore_control_ids].
    pub fn set_ignore_control_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.ignore_control_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [diversity_level][crate::model::ServingConfig::diversity_level].
    pub fn set_diversity_level<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.diversity_level = v.into();
        self
    }

    /// Sets the value of [diversity_type][crate::model::ServingConfig::diversity_type].
    pub fn set_diversity_type<
        T: std::convert::Into<crate::model::serving_config::DiversityType>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.diversity_type = v.into();
        self
    }

    /// Sets the value of [enable_category_filter_level][crate::model::ServingConfig::enable_category_filter_level].
    pub fn set_enable_category_filter_level<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.enable_category_filter_level = v.into();
        self
    }

    /// Sets the value of [ignore_recs_denylist][crate::model::ServingConfig::ignore_recs_denylist].
    pub fn set_ignore_recs_denylist<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.ignore_recs_denylist = v.into();
        self
    }

    /// Sets the value of [personalization_spec][crate::model::ServingConfig::personalization_spec].
    pub fn set_personalization_spec<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::search_request::PersonalizationSpec>,
    {
        self.personalization_spec = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [personalization_spec][crate::model::ServingConfig::personalization_spec].
    pub fn set_or_clear_personalization_spec<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::search_request::PersonalizationSpec>,
    {
        self.personalization_spec = v.map(|x| x.into());
        self
    }

    /// Sets the value of [solution_types][crate::model::ServingConfig::solution_types].
    pub fn set_solution_types<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::SolutionType>,
    {
        use std::iter::Iterator;
        self.solution_types = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ServingConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ServingConfig"
    }
}

/// Defines additional types related to [ServingConfig].
pub mod serving_config {
    #[allow(unused_imports)]
    use super::*;

    /// What type of diversity - data or rule based.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum DiversityType {
        /// Default value.
        Unspecified,
        /// Rule based diversity.
        RuleBasedDiversity,
        /// Data driven diversity.
        DataDrivenDiversity,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [DiversityType::value] or
        /// [DiversityType::name].
        UnknownValue(diversity_type::UnknownValue),
    }

    #[doc(hidden)]
    pub mod diversity_type {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl DiversityType {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::RuleBasedDiversity => std::option::Option::Some(2),
                Self::DataDrivenDiversity => std::option::Option::Some(3),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("DIVERSITY_TYPE_UNSPECIFIED"),
                Self::RuleBasedDiversity => std::option::Option::Some("RULE_BASED_DIVERSITY"),
                Self::DataDrivenDiversity => std::option::Option::Some("DATA_DRIVEN_DIVERSITY"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for DiversityType {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for DiversityType {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for DiversityType {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                2 => Self::RuleBasedDiversity,
                3 => Self::DataDrivenDiversity,
                _ => Self::UnknownValue(diversity_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for DiversityType {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "DIVERSITY_TYPE_UNSPECIFIED" => Self::Unspecified,
                "RULE_BASED_DIVERSITY" => Self::RuleBasedDiversity,
                "DATA_DRIVEN_DIVERSITY" => Self::DataDrivenDiversity,
                _ => Self::UnknownValue(diversity_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for DiversityType {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::RuleBasedDiversity => serializer.serialize_i32(2),
                Self::DataDrivenDiversity => serializer.serialize_i32(3),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for DiversityType {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<DiversityType>::new(
                ".google.cloud.retail.v2.ServingConfig.DiversityType",
            ))
        }
    }
}

/// Request for CreateServingConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CreateServingConfigRequest {
    /// Required. Full resource name of parent. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`
    pub parent: std::string::String,

    /// Required. The ServingConfig to create.
    pub serving_config: std::option::Option<crate::model::ServingConfig>,

    /// Required. The ID to use for the ServingConfig, which will become the final
    /// component of the ServingConfig's resource name.
    ///
    /// This value should be 4-63 characters, and valid characters
    /// are /[a-z][0-9]-_/.
    pub serving_config_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CreateServingConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::CreateServingConfigRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [serving_config][crate::model::CreateServingConfigRequest::serving_config].
    pub fn set_serving_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ServingConfig>,
    {
        self.serving_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [serving_config][crate::model::CreateServingConfigRequest::serving_config].
    pub fn set_or_clear_serving_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ServingConfig>,
    {
        self.serving_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [serving_config_id][crate::model::CreateServingConfigRequest::serving_config_id].
    pub fn set_serving_config_id<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.serving_config_id = v.into();
        self
    }
}

impl wkt::message::Message for CreateServingConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CreateServingConfigRequest"
    }
}

/// Request for UpdateServingConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateServingConfigRequest {
    /// Required. The ServingConfig to update.
    pub serving_config: std::option::Option<crate::model::ServingConfig>,

    /// Indicates which fields in the provided
    /// [ServingConfig][google.cloud.retail.v2.ServingConfig] to update. The
    /// following are NOT supported:
    ///
    /// * [ServingConfig.name][google.cloud.retail.v2.ServingConfig.name]
    ///
    /// If not set, all supported fields are updated.
    ///
    /// [google.cloud.retail.v2.ServingConfig]: crate::model::ServingConfig
    /// [google.cloud.retail.v2.ServingConfig.name]: crate::model::ServingConfig::name
    pub update_mask: std::option::Option<wkt::FieldMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateServingConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [serving_config][crate::model::UpdateServingConfigRequest::serving_config].
    pub fn set_serving_config<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ServingConfig>,
    {
        self.serving_config = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [serving_config][crate::model::UpdateServingConfigRequest::serving_config].
    pub fn set_or_clear_serving_config<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ServingConfig>,
    {
        self.serving_config = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateServingConfigRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateServingConfigRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::FieldMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateServingConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UpdateServingConfigRequest"
    }
}

/// Request for DeleteServingConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DeleteServingConfigRequest {
    /// Required. The resource name of the ServingConfig to delete. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DeleteServingConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::DeleteServingConfigRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for DeleteServingConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.DeleteServingConfigRequest"
    }
}

/// Request for GetServingConfig method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetServingConfigRequest {
    /// Required. The resource name of the ServingConfig to get. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`
    pub name: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetServingConfigRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetServingConfigRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }
}

impl wkt::message::Message for GetServingConfigRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.GetServingConfigRequest"
    }
}

/// Request for ListServingConfigs method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListServingConfigsRequest {
    /// Required. The catalog resource name. Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`
    pub parent: std::string::String,

    /// Optional. Maximum number of results to return. If unspecified, defaults
    /// to 100. If a value greater than 100 is provided, at most 100 results are
    /// returned.
    pub page_size: i32,

    /// Optional. A page token, received from a previous `ListServingConfigs` call.
    /// Provide this to retrieve the subsequent page.
    pub page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListServingConfigsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListServingConfigsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListServingConfigsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListServingConfigsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListServingConfigsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListServingConfigsRequest"
    }
}

/// Response for ListServingConfigs method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListServingConfigsResponse {
    /// All the ServingConfigs for a given catalog.
    pub serving_configs: std::vec::Vec<crate::model::ServingConfig>,

    /// Pagination token, if not returned indicates the last page.
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListServingConfigsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [serving_configs][crate::model::ListServingConfigsResponse::serving_configs].
    pub fn set_serving_configs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ServingConfig>,
    {
        use std::iter::Iterator;
        self.serving_configs = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListServingConfigsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListServingConfigsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ListServingConfigsResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for ListServingConfigsResponse {
    type PageItem = crate::model::ServingConfig;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.serving_configs
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// Request for AddControl method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AddControlRequest {
    /// Required. The source ServingConfig resource name . Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`
    pub serving_config: std::string::String,

    /// Required. The id of the control to apply. Assumed to be in the same catalog
    /// as the serving config - if id is not found a NOT_FOUND error is returned.
    pub control_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AddControlRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [serving_config][crate::model::AddControlRequest::serving_config].
    pub fn set_serving_config<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.serving_config = v.into();
        self
    }

    /// Sets the value of [control_id][crate::model::AddControlRequest::control_id].
    pub fn set_control_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.control_id = v.into();
        self
    }
}

impl wkt::message::Message for AddControlRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.AddControlRequest"
    }
}

/// Request for RemoveControl method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RemoveControlRequest {
    /// Required. The source ServingConfig resource name . Format:
    /// `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`
    pub serving_config: std::string::String,

    /// Required. The id of the control to apply. Assumed to be in the same catalog
    /// as the serving config.
    pub control_id: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RemoveControlRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [serving_config][crate::model::RemoveControlRequest::serving_config].
    pub fn set_serving_config<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.serving_config = v.into();
        self
    }

    /// Sets the value of [control_id][crate::model::RemoveControlRequest::control_id].
    pub fn set_control_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.control_id = v.into();
        self
    }
}

impl wkt::message::Message for RemoveControlRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RemoveControlRequest"
    }
}

/// UserEvent captures all metadata information Retail API needs to know about
/// how end users interact with customers' website.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UserEvent {
    /// Required. User event type. Allowed values are:
    ///
    /// * `add-to-cart`: Products being added to cart.
    /// * `remove-from-cart`: Products being removed from cart.
    /// * `category-page-view`: Special pages such as sale or promotion pages
    ///   viewed.
    /// * `detail-page-view`: Products detail page viewed.
    /// * `home-page-view`: Homepage viewed.
    /// * `purchase-complete`: User finishing a purchase.
    /// * `search`: Product search.
    /// * `shopping-cart-page-view`: User viewing a shopping cart.
    pub event_type: std::string::String,

    /// Required. A unique identifier for tracking visitors.
    ///
    /// For example, this could be implemented with an HTTP cookie, which should be
    /// able to uniquely identify a visitor on a single device. This unique
    /// identifier should not change if the visitor log in/out of the website.
    ///
    /// Don't set the field to the same fixed ID for different users. This mixes
    /// the event history of those users together, which results in degraded model
    /// quality.
    ///
    /// The field must be a UTF-8 encoded string with a length limit of 128
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// The field should not contain PII or user-data. We recommend to use Google
    /// Analytics [Client
    /// ID](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#clientId)
    /// for this field.
    pub visitor_id: std::string::String,

    /// A unique identifier for tracking a visitor session with a length limit of
    /// 128 bytes. A session is an aggregation of an end user behavior in a time
    /// span.
    ///
    /// A general guideline to populate the session_id:
    ///
    /// 1. If user has no activity for 30 min, a new session_id should be assigned.
    /// 1. The session_id should be unique across users, suggest use uuid or add
    ///    visitor_id as prefix.
    pub session_id: std::string::String,

    /// Only required for
    /// [UserEventService.ImportUserEvents][google.cloud.retail.v2.UserEventService.ImportUserEvents]
    /// method. Timestamp of when the user event happened.
    ///
    /// [google.cloud.retail.v2.UserEventService.ImportUserEvents]: crate::client::UserEventService::import_user_events
    pub event_time: std::option::Option<wkt::Timestamp>,

    /// A list of identifiers for the independent experiment groups this user event
    /// belongs to. This is used to distinguish between user events associated with
    /// different experiment setups (e.g. using Retail API, using different
    /// recommendation models).
    pub experiment_ids: std::vec::Vec<std::string::String>,

    /// Highly recommended for user events that are the result of
    /// [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict].
    /// This field enables accurate attribution of recommendation model
    /// performance.
    ///
    /// The value must be a valid
    /// [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token]
    /// for user events that are the result of
    /// [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict].
    /// The value must be a valid
    /// [SearchResponse.attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token]
    /// for user events that are the result of
    /// [SearchService.Search][google.cloud.retail.v2.SearchService.Search].
    ///
    /// This token enables us to accurately attribute page view or purchase back to
    /// the event and the particular predict response containing this
    /// clicked/purchased product. If user clicks on product K in the
    /// recommendation results, pass
    /// [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token]
    /// as a URL parameter to product K's page. When recording events on product
    /// K's page, log the
    /// [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token]
    /// to this field.
    ///
    /// [google.cloud.retail.v2.PredictResponse.attribution_token]: crate::model::PredictResponse::attribution_token
    /// [google.cloud.retail.v2.PredictionService.Predict]: crate::client::PredictionService::predict
    /// [google.cloud.retail.v2.SearchResponse.attribution_token]: crate::model::SearchResponse::attribution_token
    /// [google.cloud.retail.v2.SearchService.Search]: crate::client::SearchService::search
    pub attribution_token: std::string::String,

    /// The main product details related to the event.
    ///
    /// This field is optional except for the following event types:
    ///
    /// * `add-to-cart`
    /// * `detail-page-view`
    /// * `purchase-complete`
    ///
    /// In a `search` event, this field represents the products returned to the end
    /// user on the current page (the end user may have not finished browsing the
    /// whole page yet). When a new page is returned to the end user, after
    /// pagination/filtering/ordering even for the same query, a new `search` event
    /// with different
    /// [product_details][google.cloud.retail.v2.UserEvent.product_details] is
    /// desired. The end user may have not finished browsing the whole page yet.
    ///
    /// [google.cloud.retail.v2.UserEvent.product_details]: crate::model::UserEvent::product_details
    pub product_details: std::vec::Vec<crate::model::ProductDetail>,

    /// The main auto-completion details related to the event.
    ///
    /// This field should be set for `search` event when autocomplete function is
    /// enabled and the user clicks a suggestion for search.
    pub completion_detail: std::option::Option<crate::model::CompletionDetail>,

    /// Extra user event features to include in the recommendation model.
    ///
    /// If you provide custom attributes for ingested user events, also include
    /// them in the user events that you associate with prediction requests. Custom
    /// attribute formatting must be consistent between imported events and events
    /// provided with prediction requests. This lets the Retail API use
    /// those custom attributes when training models and serving predictions, which
    /// helps improve recommendation quality.
    ///
    /// This field needs to pass all below criteria, otherwise an INVALID_ARGUMENT
    /// error is returned:
    ///
    /// * The key must be a UTF-8 encoded string with a length limit of 5,000
    ///   characters.
    /// * For text attributes, at most 400 values are allowed. Empty values are not
    ///   allowed. Each value must be a UTF-8 encoded string with a length limit of
    ///   256 characters.
    /// * For number attributes, at most 400 values are allowed.
    ///
    /// For product recommendations, an example of extra user information is
    /// traffic_channel, which is how a user arrives at the site. Users can arrive
    /// at the site by coming to the site directly, coming through Google
    /// search, or in other ways.
    pub attributes: std::collections::HashMap<std::string::String, crate::model::CustomAttribute>,

    /// The ID or name of the associated shopping cart. This ID is used
    /// to associate multiple items added or present in the cart before purchase.
    ///
    /// This can only be set for `add-to-cart`, `purchase-complete`, or
    /// `shopping-cart-page-view` events.
    pub cart_id: std::string::String,

    /// A transaction represents the entire purchase transaction.
    ///
    /// Required for `purchase-complete` events. Other event types should not set
    /// this field. Otherwise, an INVALID_ARGUMENT error is returned.
    pub purchase_transaction: std::option::Option<crate::model::PurchaseTransaction>,

    /// The user's search query.
    ///
    /// See [SearchRequest.query][google.cloud.retail.v2.SearchRequest.query] for
    /// definition.
    ///
    /// The value must be a UTF-8 encoded string with a length limit of 5,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// At least one of
    /// [search_query][google.cloud.retail.v2.UserEvent.search_query] or
    /// [page_categories][google.cloud.retail.v2.UserEvent.page_categories] is
    /// required for `search` events. Other event types should not set this field.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.SearchRequest.query]: crate::model::SearchRequest::query
    /// [google.cloud.retail.v2.UserEvent.page_categories]: crate::model::UserEvent::page_categories
    /// [google.cloud.retail.v2.UserEvent.search_query]: crate::model::UserEvent::search_query
    pub search_query: std::string::String,

    /// The filter syntax consists of an expression language for constructing a
    /// predicate from one or more fields of the products being filtered.
    ///
    /// See [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
    /// definition and syntax.
    ///
    /// The value must be a UTF-8 encoded string with a length limit of 1,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.SearchRequest.filter]: crate::model::SearchRequest::filter
    pub filter: std::string::String,

    /// The order in which products are returned.
    ///
    /// See [SearchRequest.order_by][google.cloud.retail.v2.SearchRequest.order_by]
    /// for definition and syntax.
    ///
    /// The value must be a UTF-8 encoded string with a length limit of 1,000
    /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// This can only be set for `search` events. Other event types should not set
    /// this field. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.SearchRequest.order_by]: crate::model::SearchRequest::order_by
    pub order_by: std::string::String,

    /// An integer that specifies the current offset for pagination (the 0-indexed
    /// starting location, amongst the products deemed by the API as relevant).
    ///
    /// See [SearchRequest.offset][google.cloud.retail.v2.SearchRequest.offset] for
    /// definition.
    ///
    /// If this field is negative, an INVALID_ARGUMENT is returned.
    ///
    /// This can only be set for `search` events. Other event types should not set
    /// this field. Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.SearchRequest.offset]: crate::model::SearchRequest::offset
    pub offset: i32,

    /// The categories associated with a category page.
    ///
    /// To represent full path of category, use '>' sign to separate different
    /// hierarchies. If '>' is part of the category name, replace it with
    /// other character(s).
    ///
    /// Category pages include special pages such as sales or promotions. For
    /// instance, a special sale page may have the category hierarchy:
    /// "pageCategories" : ["Sales > 2017 Black Friday Deals"].
    ///
    /// Required for `category-page-view` events. At least one of
    /// [search_query][google.cloud.retail.v2.UserEvent.search_query] or
    /// [page_categories][google.cloud.retail.v2.UserEvent.page_categories] is
    /// required for `search` events. Other event types should not set this field.
    /// Otherwise, an INVALID_ARGUMENT error is returned.
    ///
    /// [google.cloud.retail.v2.UserEvent.page_categories]: crate::model::UserEvent::page_categories
    /// [google.cloud.retail.v2.UserEvent.search_query]: crate::model::UserEvent::search_query
    pub page_categories: std::vec::Vec<std::string::String>,

    /// User information.
    pub user_info: std::option::Option<crate::model::UserInfo>,

    /// Complete URL (window.location.href) of the user's current page.
    ///
    /// When using the client side event reporting with JavaScript pixel and Google
    /// Tag Manager, this value is filled in automatically. Maximum length 5,000
    /// characters.
    pub uri: std::string::String,

    /// The referrer URL of the current page.
    ///
    /// When using the client side event reporting with JavaScript pixel and Google
    /// Tag Manager, this value is filled in automatically.
    pub referrer_uri: std::string::String,

    /// A unique ID of a web page view.
    ///
    /// This should be kept the same for all user events triggered from the same
    /// pageview. For example, an item detail page view could trigger multiple
    /// events as the user is browsing the page. The `pageViewId` property should
    /// be kept the same for all these events so that they can be grouped together
    /// properly.
    ///
    /// When using the client side event reporting with JavaScript pixel and Google
    /// Tag Manager, this value is filled in automatically.
    pub page_view_id: std::string::String,

    /// The entity for customers that may run multiple different entities, domains,
    /// sites or regions, for example, `Google US`, `Google Ads`, `Waymo`,
    /// `google.com`, `youtube.com`, etc.
    /// We recommend that you set this field to get better per-entity search,
    /// completion, and prediction results.
    pub entity: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UserEvent {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [event_type][crate::model::UserEvent::event_type].
    pub fn set_event_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.event_type = v.into();
        self
    }

    /// Sets the value of [visitor_id][crate::model::UserEvent::visitor_id].
    pub fn set_visitor_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.visitor_id = v.into();
        self
    }

    /// Sets the value of [session_id][crate::model::UserEvent::session_id].
    pub fn set_session_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.session_id = v.into();
        self
    }

    /// Sets the value of [event_time][crate::model::UserEvent::event_time].
    pub fn set_event_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.event_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [event_time][crate::model::UserEvent::event_time].
    pub fn set_or_clear_event_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.event_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [experiment_ids][crate::model::UserEvent::experiment_ids].
    pub fn set_experiment_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.experiment_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [attribution_token][crate::model::UserEvent::attribution_token].
    pub fn set_attribution_token<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.attribution_token = v.into();
        self
    }

    /// Sets the value of [product_details][crate::model::UserEvent::product_details].
    pub fn set_product_details<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ProductDetail>,
    {
        use std::iter::Iterator;
        self.product_details = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [completion_detail][crate::model::UserEvent::completion_detail].
    pub fn set_completion_detail<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDetail>,
    {
        self.completion_detail = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [completion_detail][crate::model::UserEvent::completion_detail].
    pub fn set_or_clear_completion_detail<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::CompletionDetail>,
    {
        self.completion_detail = v.map(|x| x.into());
        self
    }

    /// Sets the value of [attributes][crate::model::UserEvent::attributes].
    pub fn set_attributes<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::CustomAttribute>,
    {
        use std::iter::Iterator;
        self.attributes = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [cart_id][crate::model::UserEvent::cart_id].
    pub fn set_cart_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.cart_id = v.into();
        self
    }

    /// Sets the value of [purchase_transaction][crate::model::UserEvent::purchase_transaction].
    pub fn set_purchase_transaction<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::PurchaseTransaction>,
    {
        self.purchase_transaction = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [purchase_transaction][crate::model::UserEvent::purchase_transaction].
    pub fn set_or_clear_purchase_transaction<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::PurchaseTransaction>,
    {
        self.purchase_transaction = v.map(|x| x.into());
        self
    }

    /// Sets the value of [search_query][crate::model::UserEvent::search_query].
    pub fn set_search_query<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.search_query = v.into();
        self
    }

    /// Sets the value of [filter][crate::model::UserEvent::filter].
    pub fn set_filter<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.filter = v.into();
        self
    }

    /// Sets the value of [order_by][crate::model::UserEvent::order_by].
    pub fn set_order_by<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.order_by = v.into();
        self
    }

    /// Sets the value of [offset][crate::model::UserEvent::offset].
    pub fn set_offset<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.offset = v.into();
        self
    }

    /// Sets the value of [page_categories][crate::model::UserEvent::page_categories].
    pub fn set_page_categories<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.page_categories = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [user_info][crate::model::UserEvent::user_info].
    pub fn set_user_info<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserInfo>,
    {
        self.user_info = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [user_info][crate::model::UserEvent::user_info].
    pub fn set_or_clear_user_info<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserInfo>,
    {
        self.user_info = v.map(|x| x.into());
        self
    }

    /// Sets the value of [uri][crate::model::UserEvent::uri].
    pub fn set_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.uri = v.into();
        self
    }

    /// Sets the value of [referrer_uri][crate::model::UserEvent::referrer_uri].
    pub fn set_referrer_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.referrer_uri = v.into();
        self
    }

    /// Sets the value of [page_view_id][crate::model::UserEvent::page_view_id].
    pub fn set_page_view_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_view_id = v.into();
        self
    }

    /// Sets the value of [entity][crate::model::UserEvent::entity].
    pub fn set_entity<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.entity = v.into();
        self
    }
}

impl wkt::message::Message for UserEvent {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.UserEvent"
    }
}

/// Detailed product information associated with a user event.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ProductDetail {
    /// Required. [Product][google.cloud.retail.v2.Product] information.
    ///
    /// Required field(s):
    ///
    /// * [Product.id][google.cloud.retail.v2.Product.id]
    ///
    /// Optional override field(s):
    ///
    /// * [Product.price_info][google.cloud.retail.v2.Product.price_info]
    ///
    /// If any supported optional fields are provided, we will treat them as a full
    /// override when looking up product information from the catalog. Thus, it is
    /// important to ensure that the overriding fields are accurate and
    /// complete.
    ///
    /// All other product fields are ignored and instead populated via catalog
    /// lookup after event ingestion.
    ///
    /// [google.cloud.retail.v2.Product]: crate::model::Product
    /// [google.cloud.retail.v2.Product.id]: crate::model::Product::id
    /// [google.cloud.retail.v2.Product.price_info]: crate::model::Product::price_info
    pub product: std::option::Option<crate::model::Product>,

    /// Quantity of the product associated with the user event.
    ///
    /// For example, this field will be 2 if two products are added to the shopping
    /// cart for `purchase-complete` event. Required for `add-to-cart` and
    /// `purchase-complete` event types.
    pub quantity: std::option::Option<wkt::Int32Value>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ProductDetail {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [product][crate::model::ProductDetail::product].
    pub fn set_product<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.product = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [product][crate::model::ProductDetail::product].
    pub fn set_or_clear_product<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Product>,
    {
        self.product = v.map(|x| x.into());
        self
    }

    /// Sets the value of [quantity][crate::model::ProductDetail::quantity].
    pub fn set_quantity<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.quantity = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [quantity][crate::model::ProductDetail::quantity].
    pub fn set_or_clear_quantity<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.quantity = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ProductDetail {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.ProductDetail"
    }
}

/// Detailed completion information including completion attribution token and
/// clicked completion info.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CompletionDetail {
    /// Completion attribution token in
    /// [CompleteQueryResponse.attribution_token][google.cloud.retail.v2.CompleteQueryResponse.attribution_token].
    ///
    /// [google.cloud.retail.v2.CompleteQueryResponse.attribution_token]: crate::model::CompleteQueryResponse::attribution_token
    pub completion_attribution_token: std::string::String,

    /// End user selected
    /// [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion].
    ///
    /// [google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion]: crate::model::complete_query_response::CompletionResult::suggestion
    pub selected_suggestion: std::string::String,

    /// End user selected
    /// [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion]
    /// position, starting from 0.
    ///
    /// [google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion]: crate::model::complete_query_response::CompletionResult::suggestion
    pub selected_position: i32,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CompletionDetail {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [completion_attribution_token][crate::model::CompletionDetail::completion_attribution_token].
    pub fn set_completion_attribution_token<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.completion_attribution_token = v.into();
        self
    }

    /// Sets the value of [selected_suggestion][crate::model::CompletionDetail::selected_suggestion].
    pub fn set_selected_suggestion<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.selected_suggestion = v.into();
        self
    }

    /// Sets the value of [selected_position][crate::model::CompletionDetail::selected_position].
    pub fn set_selected_position<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.selected_position = v.into();
        self
    }
}

impl wkt::message::Message for CompletionDetail {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CompletionDetail"
    }
}

/// A transaction represents the entire purchase transaction.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PurchaseTransaction {
    /// The transaction ID with a length limit of 128 characters.
    pub id: std::string::String,

    /// Required. Total non-zero revenue or grand total associated with the
    /// transaction. This value include shipping, tax, or other adjustments to
    /// total revenue that you want to include as part of your revenue
    /// calculations.
    pub revenue: f32,

    /// All the taxes associated with the transaction.
    pub tax: f32,

    /// All the costs associated with the products. These can be manufacturing
    /// costs, shipping expenses not borne by the end user, or any other costs,
    /// such that:
    ///
    /// * Profit = [revenue][google.cloud.retail.v2.PurchaseTransaction.revenue] -
    ///   [tax][google.cloud.retail.v2.PurchaseTransaction.tax] -
    ///   [cost][google.cloud.retail.v2.PurchaseTransaction.cost]
    ///
    /// [google.cloud.retail.v2.PurchaseTransaction.cost]: crate::model::PurchaseTransaction::cost
    /// [google.cloud.retail.v2.PurchaseTransaction.revenue]: crate::model::PurchaseTransaction::revenue
    /// [google.cloud.retail.v2.PurchaseTransaction.tax]: crate::model::PurchaseTransaction::tax
    pub cost: f32,

    /// Required. Currency code. Use three-character ISO-4217 code.
    pub currency_code: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PurchaseTransaction {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [id][crate::model::PurchaseTransaction::id].
    pub fn set_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.id = v.into();
        self
    }

    /// Sets the value of [revenue][crate::model::PurchaseTransaction::revenue].
    pub fn set_revenue<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.revenue = v.into();
        self
    }

    /// Sets the value of [tax][crate::model::PurchaseTransaction::tax].
    pub fn set_tax<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.tax = v.into();
        self
    }

    /// Sets the value of [cost][crate::model::PurchaseTransaction::cost].
    pub fn set_cost<T: std::convert::Into<f32>>(mut self, v: T) -> Self {
        self.cost = v.into();
        self
    }

    /// Sets the value of [currency_code][crate::model::PurchaseTransaction::currency_code].
    pub fn set_currency_code<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.currency_code = v.into();
        self
    }
}

impl wkt::message::Message for PurchaseTransaction {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.PurchaseTransaction"
    }
}

/// Request message for WriteUserEvent method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct WriteUserEventRequest {
    /// Required. The parent catalog resource name, such as
    /// `projects/1234/locations/global/catalogs/default_catalog`.
    pub parent: std::string::String,

    /// Required. User event to write.
    pub user_event: std::option::Option<crate::model::UserEvent>,

    /// If set to true, the user event will be written asynchronously after
    /// validation, and the API will respond without waiting for the write.
    /// Therefore, silent failures can occur even if the API returns success. In
    /// case of silent failures, error messages can be found in Stackdriver logs.
    pub write_async: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl WriteUserEventRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::WriteUserEventRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [user_event][crate::model::WriteUserEventRequest::user_event].
    pub fn set_user_event<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::UserEvent>,
    {
        self.user_event = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [user_event][crate::model::WriteUserEventRequest::user_event].
    pub fn set_or_clear_user_event<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::UserEvent>,
    {
        self.user_event = v.map(|x| x.into());
        self
    }

    /// Sets the value of [write_async][crate::model::WriteUserEventRequest::write_async].
    pub fn set_write_async<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.write_async = v.into();
        self
    }
}

impl wkt::message::Message for WriteUserEventRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.WriteUserEventRequest"
    }
}

/// Request message for CollectUserEvent method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CollectUserEventRequest {
    /// Required. The parent catalog name, such as
    /// `projects/1234/locations/global/catalogs/default_catalog`.
    pub parent: std::string::String,

    /// Required. URL encoded UserEvent proto with a length limit of 2,000,000
    /// characters.
    pub user_event: std::string::String,

    /// The URL including cgi-parameters but excluding the hash fragment with a
    /// length limit of 5,000 characters. This is often more useful than the
    /// referer URL, because many browsers only send the domain for 3rd party
    /// requests.
    pub uri: std::string::String,

    /// The event timestamp in milliseconds. This prevents browser caching of
    /// otherwise identical get requests. The name is abbreviated to reduce the
    /// payload bytes.
    pub ets: i64,

    /// An arbitrary serialized JSON string that contains necessary information
    /// that can comprise a user event. When this field is specified, the
    /// user_event field will be ignored. Note: line-delimited JSON is not
    /// supported, a single JSON only.
    pub raw_json: std::string::String,

    /// The rule that can convert the raw_json to a user event. It is needed
    /// only when the raw_json is set.
    pub conversion_rule:
        std::option::Option<crate::model::collect_user_event_request::ConversionRule>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CollectUserEventRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::CollectUserEventRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [user_event][crate::model::CollectUserEventRequest::user_event].
    pub fn set_user_event<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.user_event = v.into();
        self
    }

    /// Sets the value of [uri][crate::model::CollectUserEventRequest::uri].
    pub fn set_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.uri = v.into();
        self
    }

    /// Sets the value of [ets][crate::model::CollectUserEventRequest::ets].
    pub fn set_ets<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.ets = v.into();
        self
    }

    /// Sets the value of [raw_json][crate::model::CollectUserEventRequest::raw_json].
    pub fn set_raw_json<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.raw_json = v.into();
        self
    }

    /// Sets the value of [conversion_rule][crate::model::CollectUserEventRequest::conversion_rule].
    ///
    /// Note that all the setters affecting `conversion_rule` are mutually
    /// exclusive.
    pub fn set_conversion_rule<
        T: std::convert::Into<
                std::option::Option<crate::model::collect_user_event_request::ConversionRule>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.conversion_rule = v.into();
        self
    }

    /// The value of [conversion_rule][crate::model::CollectUserEventRequest::conversion_rule]
    /// if it holds a `PrebuiltRule`, `None` if the field is not set or
    /// holds a different branch.
    pub fn prebuilt_rule(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.conversion_rule.as_ref().and_then(|v| match v {
            crate::model::collect_user_event_request::ConversionRule::PrebuiltRule(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [conversion_rule][crate::model::CollectUserEventRequest::conversion_rule]
    /// to hold a `PrebuiltRule`.
    ///
    /// Note that all the setters affecting `conversion_rule` are
    /// mutually exclusive.
    pub fn set_prebuilt_rule<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.conversion_rule = std::option::Option::Some(
            crate::model::collect_user_event_request::ConversionRule::PrebuiltRule(v.into()),
        );
        self
    }
}

impl wkt::message::Message for CollectUserEventRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.CollectUserEventRequest"
    }
}

/// Defines additional types related to [CollectUserEventRequest].
pub mod collect_user_event_request {
    #[allow(unused_imports)]
    use super::*;

    /// The rule that can convert the raw_json to a user event. It is needed
    /// only when the raw_json is set.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConversionRule {
        /// The prebuilt rule name that can convert a specific type of raw_json.
        /// For example: "ga4_bq" rule for the GA4 user event schema.
        PrebuiltRule(std::string::String),
    }
}

/// Request message for RejoinUserEvents method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RejoinUserEventsRequest {
    /// Required. The parent catalog resource name, such as
    /// `projects/1234/locations/global/catalogs/default_catalog`.
    pub parent: std::string::String,

    /// The type of the user event rejoin to define the scope and range of the user
    /// events to be rejoined with the latest product catalog. Defaults to
    /// `USER_EVENT_REJOIN_SCOPE_UNSPECIFIED` if this field is not set, or set to
    /// an invalid integer value.
    pub user_event_rejoin_scope: crate::model::rejoin_user_events_request::UserEventRejoinScope,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RejoinUserEventsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::RejoinUserEventsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [user_event_rejoin_scope][crate::model::RejoinUserEventsRequest::user_event_rejoin_scope].
    pub fn set_user_event_rejoin_scope<
        T: std::convert::Into<crate::model::rejoin_user_events_request::UserEventRejoinScope>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.user_event_rejoin_scope = v.into();
        self
    }
}

impl wkt::message::Message for RejoinUserEventsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RejoinUserEventsRequest"
    }
}

/// Defines additional types related to [RejoinUserEventsRequest].
pub mod rejoin_user_events_request {
    #[allow(unused_imports)]
    use super::*;

    /// The scope of user events to be rejoined with the latest product catalog.
    /// If the rejoining aims at reducing number of unjoined events, set
    /// `UserEventRejoinScope` to `UNJOINED_EVENTS`.
    /// If the rejoining aims at correcting product catalog information in joined
    /// events, set `UserEventRejoinScope` to `JOINED_EVENTS`.
    /// If all events needs to be rejoined, set `UserEventRejoinScope` to
    /// `USER_EVENT_REJOIN_SCOPE_UNSPECIFIED`.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum UserEventRejoinScope {
        /// Rejoin all events with the latest product catalog, including both joined
        /// events and unjoined events.
        Unspecified,
        /// Only rejoin joined events with the latest product catalog.
        JoinedEvents,
        /// Only rejoin unjoined events with the latest product catalog.
        UnjoinedEvents,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [UserEventRejoinScope::value] or
        /// [UserEventRejoinScope::name].
        UnknownValue(user_event_rejoin_scope::UnknownValue),
    }

    #[doc(hidden)]
    pub mod user_event_rejoin_scope {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl UserEventRejoinScope {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::JoinedEvents => std::option::Option::Some(1),
                Self::UnjoinedEvents => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => {
                    std::option::Option::Some("USER_EVENT_REJOIN_SCOPE_UNSPECIFIED")
                }
                Self::JoinedEvents => std::option::Option::Some("JOINED_EVENTS"),
                Self::UnjoinedEvents => std::option::Option::Some("UNJOINED_EVENTS"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for UserEventRejoinScope {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for UserEventRejoinScope {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for UserEventRejoinScope {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::JoinedEvents,
                2 => Self::UnjoinedEvents,
                _ => Self::UnknownValue(user_event_rejoin_scope::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for UserEventRejoinScope {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "USER_EVENT_REJOIN_SCOPE_UNSPECIFIED" => Self::Unspecified,
                "JOINED_EVENTS" => Self::JoinedEvents,
                "UNJOINED_EVENTS" => Self::UnjoinedEvents,
                _ => Self::UnknownValue(user_event_rejoin_scope::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for UserEventRejoinScope {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::JoinedEvents => serializer.serialize_i32(1),
                Self::UnjoinedEvents => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for UserEventRejoinScope {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<UserEventRejoinScope>::new(
                ".google.cloud.retail.v2.RejoinUserEventsRequest.UserEventRejoinScope",
            ))
        }
    }
}

/// Response message for `RejoinUserEvents` method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RejoinUserEventsResponse {
    /// Number of user events that were joined with latest product catalog.
    pub rejoined_user_events_count: i64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RejoinUserEventsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [rejoined_user_events_count][crate::model::RejoinUserEventsResponse::rejoined_user_events_count].
    pub fn set_rejoined_user_events_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.rejoined_user_events_count = v.into();
        self
    }
}

impl wkt::message::Message for RejoinUserEventsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RejoinUserEventsResponse"
    }
}

/// Metadata for `RejoinUserEvents` method.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RejoinUserEventsMetadata {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RejoinUserEventsMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for RejoinUserEventsMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.retail.v2.RejoinUserEventsMetadata"
    }
}

/// At which level we offer configuration for attributes.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum AttributeConfigLevel {
    /// Value used when unset. In this case, server behavior defaults to
    /// [CATALOG_LEVEL_ATTRIBUTE_CONFIG][google.cloud.retail.v2.AttributeConfigLevel.CATALOG_LEVEL_ATTRIBUTE_CONFIG].
    ///
    /// [google.cloud.retail.v2.AttributeConfigLevel.CATALOG_LEVEL_ATTRIBUTE_CONFIG]: crate::model::AttributeConfigLevel::CatalogLevelAttributeConfig
    Unspecified,
    /// At this level, we honor the attribute configurations set in
    /// [Product.attributes][google.cloud.retail.v2.Product.attributes].
    ///
    /// [google.cloud.retail.v2.Product.attributes]: crate::model::Product::attributes
    ProductLevelAttributeConfig,
    /// At this level, we honor the attribute configurations set in
    /// `CatalogConfig.attribute_configs`.
    CatalogLevelAttributeConfig,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [AttributeConfigLevel::value] or
    /// [AttributeConfigLevel::name].
    UnknownValue(attribute_config_level::UnknownValue),
}

#[doc(hidden)]
pub mod attribute_config_level {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl AttributeConfigLevel {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::ProductLevelAttributeConfig => std::option::Option::Some(1),
            Self::CatalogLevelAttributeConfig => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED"),
            Self::ProductLevelAttributeConfig => {
                std::option::Option::Some("PRODUCT_LEVEL_ATTRIBUTE_CONFIG")
            }
            Self::CatalogLevelAttributeConfig => {
                std::option::Option::Some("CATALOG_LEVEL_ATTRIBUTE_CONFIG")
            }
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for AttributeConfigLevel {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for AttributeConfigLevel {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for AttributeConfigLevel {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::ProductLevelAttributeConfig,
            2 => Self::CatalogLevelAttributeConfig,
            _ => Self::UnknownValue(attribute_config_level::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for AttributeConfigLevel {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED" => Self::Unspecified,
            "PRODUCT_LEVEL_ATTRIBUTE_CONFIG" => Self::ProductLevelAttributeConfig,
            "CATALOG_LEVEL_ATTRIBUTE_CONFIG" => Self::CatalogLevelAttributeConfig,
            _ => Self::UnknownValue(attribute_config_level::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for AttributeConfigLevel {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::ProductLevelAttributeConfig => serializer.serialize_i32(1),
            Self::CatalogLevelAttributeConfig => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for AttributeConfigLevel {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<AttributeConfigLevel>::new(
            ".google.cloud.retail.v2.AttributeConfigLevel",
        ))
    }
}

/// The type of solution.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum SolutionType {
    /// Default value.
    Unspecified,
    /// Used for Recommendations AI.
    Recommendation,
    /// Used for Retail Search.
    Search,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [SolutionType::value] or
    /// [SolutionType::name].
    UnknownValue(solution_type::UnknownValue),
}

#[doc(hidden)]
pub mod solution_type {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl SolutionType {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Recommendation => std::option::Option::Some(1),
            Self::Search => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("SOLUTION_TYPE_UNSPECIFIED"),
            Self::Recommendation => std::option::Option::Some("SOLUTION_TYPE_RECOMMENDATION"),
            Self::Search => std::option::Option::Some("SOLUTION_TYPE_SEARCH"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for SolutionType {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for SolutionType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for SolutionType {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Recommendation,
            2 => Self::Search,
            _ => Self::UnknownValue(solution_type::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for SolutionType {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "SOLUTION_TYPE_UNSPECIFIED" => Self::Unspecified,
            "SOLUTION_TYPE_RECOMMENDATION" => Self::Recommendation,
            "SOLUTION_TYPE_SEARCH" => Self::Search,
            _ => Self::UnknownValue(solution_type::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for SolutionType {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Recommendation => serializer.serialize_i32(1),
            Self::Search => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for SolutionType {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<SolutionType>::new(
            ".google.cloud.retail.v2.SolutionType",
        ))
    }
}

/// If filtering for recommendations is enabled.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum RecommendationsFilteringOption {
    /// Value used when unset.
    /// In this case, server behavior defaults to
    /// [RECOMMENDATIONS_FILTERING_DISABLED][google.cloud.retail.v2.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED].
    ///
    /// [google.cloud.retail.v2.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED]: crate::model::RecommendationsFilteringOption::RecommendationsFilteringDisabled
    Unspecified,
    /// Recommendation filtering is disabled.
    RecommendationsFilteringDisabled,
    /// Recommendation filtering is enabled.
    RecommendationsFilteringEnabled,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [RecommendationsFilteringOption::value] or
    /// [RecommendationsFilteringOption::name].
    UnknownValue(recommendations_filtering_option::UnknownValue),
}

#[doc(hidden)]
pub mod recommendations_filtering_option {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl RecommendationsFilteringOption {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::RecommendationsFilteringDisabled => std::option::Option::Some(1),
            Self::RecommendationsFilteringEnabled => std::option::Option::Some(3),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => {
                std::option::Option::Some("RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED")
            }
            Self::RecommendationsFilteringDisabled => {
                std::option::Option::Some("RECOMMENDATIONS_FILTERING_DISABLED")
            }
            Self::RecommendationsFilteringEnabled => {
                std::option::Option::Some("RECOMMENDATIONS_FILTERING_ENABLED")
            }
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for RecommendationsFilteringOption {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for RecommendationsFilteringOption {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for RecommendationsFilteringOption {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::RecommendationsFilteringDisabled,
            3 => Self::RecommendationsFilteringEnabled,
            _ => Self::UnknownValue(recommendations_filtering_option::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for RecommendationsFilteringOption {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED" => Self::Unspecified,
            "RECOMMENDATIONS_FILTERING_DISABLED" => Self::RecommendationsFilteringDisabled,
            "RECOMMENDATIONS_FILTERING_ENABLED" => Self::RecommendationsFilteringEnabled,
            _ => Self::UnknownValue(recommendations_filtering_option::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for RecommendationsFilteringOption {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::RecommendationsFilteringDisabled => serializer.serialize_i32(1),
            Self::RecommendationsFilteringEnabled => serializer.serialize_i32(3),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for RecommendationsFilteringOption {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(
            wkt::internal::EnumVisitor::<RecommendationsFilteringOption>::new(
                ".google.cloud.retail.v2.RecommendationsFilteringOption",
            ),
        )
    }
}

/// The use case of Cloud Retail Search.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum SearchSolutionUseCase {
    /// The value when it's unspecified. In this case, server behavior defaults to
    /// [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH].
    ///
    /// [google.cloud.retail.v2.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH]: crate::model::SearchSolutionUseCase::Search
    Unspecified,
    /// Search use case. Expects the traffic has a non-empty
    /// [query][google.cloud.retail.v2.SearchRequest.query].
    ///
    /// [google.cloud.retail.v2.SearchRequest.query]: crate::model::SearchRequest::query
    Search,
    /// Browse use case. Expects the traffic has an empty
    /// [query][google.cloud.retail.v2.SearchRequest.query].
    ///
    /// [google.cloud.retail.v2.SearchRequest.query]: crate::model::SearchRequest::query
    Browse,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [SearchSolutionUseCase::value] or
    /// [SearchSolutionUseCase::name].
    UnknownValue(search_solution_use_case::UnknownValue),
}

#[doc(hidden)]
pub mod search_solution_use_case {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl SearchSolutionUseCase {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Search => std::option::Option::Some(1),
            Self::Browse => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("SEARCH_SOLUTION_USE_CASE_UNSPECIFIED"),
            Self::Search => std::option::Option::Some("SEARCH_SOLUTION_USE_CASE_SEARCH"),
            Self::Browse => std::option::Option::Some("SEARCH_SOLUTION_USE_CASE_BROWSE"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for SearchSolutionUseCase {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for SearchSolutionUseCase {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for SearchSolutionUseCase {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Search,
            2 => Self::Browse,
            _ => Self::UnknownValue(search_solution_use_case::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for SearchSolutionUseCase {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "SEARCH_SOLUTION_USE_CASE_UNSPECIFIED" => Self::Unspecified,
            "SEARCH_SOLUTION_USE_CASE_SEARCH" => Self::Search,
            "SEARCH_SOLUTION_USE_CASE_BROWSE" => Self::Browse,
            _ => Self::UnknownValue(search_solution_use_case::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for SearchSolutionUseCase {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Search => serializer.serialize_i32(1),
            Self::Browse => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for SearchSolutionUseCase {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<SearchSolutionUseCase>::new(
            ".google.cloud.retail.v2.SearchSolutionUseCase",
        ))
    }
}

/// Harm categories that will block the content.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum HarmCategory {
    /// The harm category is unspecified.
    Unspecified,
    /// The harm category is hate speech.
    HateSpeech,
    /// The harm category is dangerous content.
    DangerousContent,
    /// The harm category is harassment.
    Harassment,
    /// The harm category is sexually explicit content.
    SexuallyExplicit,
    /// The harm category is civic integrity.
    CivicIntegrity,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [HarmCategory::value] or
    /// [HarmCategory::name].
    UnknownValue(harm_category::UnknownValue),
}

#[doc(hidden)]
pub mod harm_category {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl HarmCategory {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::HateSpeech => std::option::Option::Some(1),
            Self::DangerousContent => std::option::Option::Some(2),
            Self::Harassment => std::option::Option::Some(3),
            Self::SexuallyExplicit => std::option::Option::Some(4),
            Self::CivicIntegrity => std::option::Option::Some(5),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("HARM_CATEGORY_UNSPECIFIED"),
            Self::HateSpeech => std::option::Option::Some("HARM_CATEGORY_HATE_SPEECH"),
            Self::DangerousContent => std::option::Option::Some("HARM_CATEGORY_DANGEROUS_CONTENT"),
            Self::Harassment => std::option::Option::Some("HARM_CATEGORY_HARASSMENT"),
            Self::SexuallyExplicit => std::option::Option::Some("HARM_CATEGORY_SEXUALLY_EXPLICIT"),
            Self::CivicIntegrity => std::option::Option::Some("HARM_CATEGORY_CIVIC_INTEGRITY"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for HarmCategory {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for HarmCategory {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for HarmCategory {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::HateSpeech,
            2 => Self::DangerousContent,
            3 => Self::Harassment,
            4 => Self::SexuallyExplicit,
            5 => Self::CivicIntegrity,
            _ => Self::UnknownValue(harm_category::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for HarmCategory {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "HARM_CATEGORY_UNSPECIFIED" => Self::Unspecified,
            "HARM_CATEGORY_HATE_SPEECH" => Self::HateSpeech,
            "HARM_CATEGORY_DANGEROUS_CONTENT" => Self::DangerousContent,
            "HARM_CATEGORY_HARASSMENT" => Self::Harassment,
            "HARM_CATEGORY_SEXUALLY_EXPLICIT" => Self::SexuallyExplicit,
            "HARM_CATEGORY_CIVIC_INTEGRITY" => Self::CivicIntegrity,
            _ => Self::UnknownValue(harm_category::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for HarmCategory {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::HateSpeech => serializer.serialize_i32(1),
            Self::DangerousContent => serializer.serialize_i32(2),
            Self::Harassment => serializer.serialize_i32(3),
            Self::SexuallyExplicit => serializer.serialize_i32(4),
            Self::CivicIntegrity => serializer.serialize_i32(5),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for HarmCategory {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<HarmCategory>::new(
            ".google.cloud.retail.v2.HarmCategory",
        ))
    }
}
